* [Qemu-devel] [PATCH 02/11] Add migrate_set_parameter and query-migrate-parameters
2012-07-25 14:50 [Qemu-devel] [PATCH 00/11] Migration next v6 Orit Wasserman
@ 2012-07-25 14:50 ` Orit Wasserman
0 siblings, 0 replies; 32+ messages in thread
From: Orit Wasserman @ 2012-07-25 14:50 UTC (permalink / raw)
To: qemu-devel
Cc: peter.maydell, aliguori, quintela, stefanha, mdroth, lcapitulino,
blauwirbel, Orit Wasserman, chegu_vinod, avi, pbonzini, eblake
The management can enable/disable a capability for the next migration by using
migrate_set_parameter command.
The management can query the current migration capabilities using
query-migrate-parameters
Signed-off-by: Orit Wasserman <owasserm@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
---
hmp-commands.hx | 16 ++++++++++++
hmp.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
hmp.h | 2 +
migration.c | 42 +++++++++++++++++++++++++++++++-
migration.h | 2 +
monitor.c | 7 +++++
qapi-schema.json | 32 ++++++++++++++++++++++++
qmp-commands.hx | 60 ++++++++++++++++++++++++++++++++++++++++++++-
8 files changed, 229 insertions(+), 3 deletions(-)
diff --git a/hmp-commands.hx b/hmp-commands.hx
index 8786148..3e15338 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 = "capability state",
+ .help = "Enable/Disable 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 user network stack connection states
show migration status
@item info migration_capabilities
show migration capabilities
+@item info migrate_parameters
+show current migration parameters
@item info balloon
show balloon information
@item info qtree
diff --git a/hmp.c b/hmp.c
index 5c7d0be..f2f63fd 100644
--- a/hmp.c
+++ b/hmp.c
@@ -131,8 +131,22 @@ void hmp_info_mice(Monitor *mon)
void hmp_info_migrate(Monitor *mon)
{
MigrationInfo *info;
+ MigrationCapabilityStatusList *cap;
+ MigrationParameters *params;
info = qmp_query_migrate(NULL);
+ params = qmp_query_migrate_parameters(NULL);
+
+ /* do not display parameters during setup */
+ if (info->has_status && params->capabilities) {
+ monitor_printf(mon, "capabilities: ");
+ for (cap = params->capabilities; 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 +173,7 @@ void hmp_info_migrate(Monitor *mon)
}
qapi_free_MigrationInfo(info);
+ qapi_free_MigrationParameters(params);
}
void hmp_info_migration_capabilities(Monitor *mon)
@@ -180,6 +195,27 @@ void hmp_info_migration_capabilities(Monitor *mon)
qapi_free_MigrationCapabilityStatusList(caps_list);
}
+void hmp_info_migrate_parameters(Monitor *mon)
+{
+
+ MigrationCapabilityStatusList *cap;
+ MigrationParameters *params;
+
+ params = qmp_query_migrate_parameters(NULL);
+
+ if (params->capabilities) {
+ monitor_printf(mon, "capabilities: ");
+ for (cap = params->capabilities; cap; cap = cap->next) {
+ monitor_printf(mon, "%s: %s ",
+ MigrationCapability_lookup[cap->value->capability],
+ cap->value->state ? "on" : "off");
+ }
+ monitor_printf(mon, "\n");
+ }
+
+ qapi_free_MigrationParameters(params);
+}
+
void hmp_info_cpus(Monitor *mon)
{
CpuInfoList *cpu_list, *cpu;
@@ -754,6 +790,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;
+ MigrationCapabilityStatusList *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_MigrationCapabilityStatusList(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 2fb44ca..ceb2f06 100644
--- a/hmp.h
+++ b/hmp.h
@@ -26,6 +26,7 @@ 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_migrate_parameters(Monitor *mon);
void hmp_info_cpus(Monitor *mon);
void hmp_info_block(Monitor *mon);
void hmp_info_blockstats(Monitor *mon);
@@ -52,6 +53,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 8c27347..e844290 100644
--- a/migration.c
+++ b/migration.c
@@ -113,6 +113,25 @@ uint64_t migrate_max_downtime(void)
return max_downtime;
}
+MigrationParameters *qmp_query_migrate_parameters(Error **errp)
+{
+ MigrationParameters *params = g_malloc0(sizeof(*params));
+ MigrationState *s = migrate_get_current();
+ int i;
+
+ params->capabilities = g_malloc0(sizeof(*params->capabilities));
+
+ for (i = 0; i < MIGRATION_CAPABILITY_MAX; i++) {
+ params->capabilities->value =
+ g_malloc(sizeof(*params->capabilities->value));
+ params->capabilities->value->capability = i;
+ params->capabilities->value->state = s->enabled_capabilities[i];
+ params->capabilities->next = NULL;
+ }
+
+ return params;
+}
+
MigrationInfo *qmp_query_migrate(Error **errp)
{
MigrationInfo *info = g_malloc0(sizeof(*info));
@@ -177,6 +196,22 @@ MigrationCapabilityStatusList *qmp_query_migration_capabilities(Error **errp)
return caps_list;
}
+void qmp_migrate_set_parameters(MigrationCapabilityStatusList *params,
+ Error **errp)
+{
+ MigrationState *s = migrate_get_current();
+ MigrationCapabilityStatusList *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)
@@ -386,12 +421,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;
s->total_time = qemu_get_clock_ms(rt_clock);
diff --git a/migration.h b/migration.h
index 57572a6..713aae0 100644
--- a/migration.h
+++ b/migration.h
@@ -19,6 +19,7 @@
#include "notify.h"
#include "error.h"
#include "vmstate.h"
+#include "qapi-types.h"
struct MigrationParams {
bool blk;
@@ -39,6 +40,7 @@ struct MigrationState
void *opaque;
MigrationParams params;
int64_t total_time;
+ bool enabled_capabilities[MIGRATION_CAPABILITY_MAX];
};
void process_incoming_migration(QEMUFile *f);
diff --git a/monitor.c b/monitor.c
index fd57c5e..e07af97 100644
--- a/monitor.c
+++ b/monitor.c
@@ -2669,6 +2669,13 @@ static mon_cmd_t info_cmds[] = {
.mhandler.info = hmp_info_migration_capabilities,
},
{
+ .name = "migrate-parameters",
+ .args_type = "",
+ .params = "",
+ .help = "show current migration parameters",
+ .mhandler.info = hmp_info_migrate_parameters,
+ },
+ {
.name = "balloon",
.args_type = "",
.params = "",
diff --git a/qapi-schema.json b/qapi-schema.json
index b4d4dd6..9d6759d 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -345,6 +345,38 @@
{ 'command': 'query-migration-capabilities', 'returns': ['MigrationCapabilityStatus'] }
##
+# @migrate-set-parameters
+#
+# Enable/Disable the following migration capabilities (like xbzrle)
+#
+# Since: 1.2
+##
+{ 'command': 'migrate-set-parameters',
+ 'data': { 'capabilities': ['MigrationCapabilityStatus'] } }
+
+##
+# @MigrationParameters
+#
+# @capabilities: @MigrationCapabilityStatus list contain current migration
+# capabilities status
+# Since: 1.2
+##
+{ 'type': 'MigrationParameters',
+ 'data': {'capabilities': ['MigrationCapabilityStatus']} }
+
+
+##
+# @query-migrate-parameters
+#
+# Returns information about the current migration capabilities status
+#
+# Returns: @MigrationParameters
+#
+# Since: 1.2
+##
+{ 'command': 'query-migrate-parameters', 'returns': 'MigrationParameters' }
+
+##
# @MouseInfo:
#
# Information about a mouse device.
diff --git a/qmp-commands.hx b/qmp-commands.hx
index c0ed14c..7f40e2a 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -2081,7 +2081,6 @@ The main json-object contains the following:
- "transferred": amount transferred (json-int)
- "remaining": amount remaining (json-int)
- "total": total (json-int)
-
Examples:
1. Before the first migration
@@ -2092,7 +2091,15 @@ Examples:
2. Migration is done and has succeeded
-> { "execute": "query-migrate" }
-<- { "return": { "status": "completed" } }
+<- { "return": {
+ "status": "completed",
+ "ram":{
+ "transferred":123,
+ "remaining":123,
+ "total":246
+ }
+ }
+ }
3. Migration is done and has failed
@@ -2165,6 +2172,55 @@ EQMP
},
SQMP
+migrate-set-parameters
+-------
+
+Enable/Disable 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-migrate-parameters
+-------
+
+Query current migration parameters
+
+- "capabilities": migration capabilities state
+ - "xbzrle" : XBZRLE state (json-bool)
+
+Arguments:
+
+Example:
+
+-> { "execute": "query-migrate-parameters" }
+<- { "return": {
+ "capabilities" : [ { "capability" : "xbzrle", "state" : false } ]
+ }
+ }
+EQMP
+
+ {
+ .name = "query-migrate-parameters",
+ .args_type = "",
+ .mhandler.cmd_new = qmp_marshal_input_query_migrate_parameters,
+ },
+
+SQMP
query-balloon
-------------
--
1.7.7.6
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [Qemu-devel] [PATCH 02/11] Add migrate_set_parameter and query-migrate-parameters
2012-07-29 9:42 [Qemu-devel] [PATCH 00/11] Migration next v7 Orit Wasserman
@ 2012-07-29 9:42 ` Orit Wasserman
2012-07-30 17:41 ` Luiz Capitulino
` (3 more replies)
0 siblings, 4 replies; 32+ messages in thread
From: Orit Wasserman @ 2012-07-29 9:42 UTC (permalink / raw)
To: qemu-devel
Cc: peter.maydell, aliguori, quintela, stefanha, mdroth, lcapitulino,
blauwirbel, Orit Wasserman, chegu_vinod, avi, pbonzini, eblake
The management can enable/disable a capability for the next migration by using
migrate_set_parameter command.
The management can query the current migration capabilities using
query-migrate-parameters
Signed-off-by: Orit Wasserman <owasserm@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
---
hmp-commands.hx | 16 ++++++++++++
hmp.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
hmp.h | 2 +
migration.c | 42 +++++++++++++++++++++++++++++++-
migration.h | 2 +
monitor.c | 7 +++++
qapi-schema.json | 32 ++++++++++++++++++++++++
qmp-commands.hx | 60 ++++++++++++++++++++++++++++++++++++++++++++-
8 files changed, 229 insertions(+), 3 deletions(-)
diff --git a/hmp-commands.hx b/hmp-commands.hx
index 8786148..3e15338 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 = "capability state",
+ .help = "Enable/Disable 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 user network stack connection states
show migration status
@item info migration_capabilities
show migration capabilities
+@item info migrate_parameters
+show current migration parameters
@item info balloon
show balloon information
@item info qtree
diff --git a/hmp.c b/hmp.c
index 5c7d0be..f2f63fd 100644
--- a/hmp.c
+++ b/hmp.c
@@ -131,8 +131,22 @@ void hmp_info_mice(Monitor *mon)
void hmp_info_migrate(Monitor *mon)
{
MigrationInfo *info;
+ MigrationCapabilityStatusList *cap;
+ MigrationParameters *params;
info = qmp_query_migrate(NULL);
+ params = qmp_query_migrate_parameters(NULL);
+
+ /* do not display parameters during setup */
+ if (info->has_status && params->capabilities) {
+ monitor_printf(mon, "capabilities: ");
+ for (cap = params->capabilities; 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 +173,7 @@ void hmp_info_migrate(Monitor *mon)
}
qapi_free_MigrationInfo(info);
+ qapi_free_MigrationParameters(params);
}
void hmp_info_migration_capabilities(Monitor *mon)
@@ -180,6 +195,27 @@ void hmp_info_migration_capabilities(Monitor *mon)
qapi_free_MigrationCapabilityStatusList(caps_list);
}
+void hmp_info_migrate_parameters(Monitor *mon)
+{
+
+ MigrationCapabilityStatusList *cap;
+ MigrationParameters *params;
+
+ params = qmp_query_migrate_parameters(NULL);
+
+ if (params->capabilities) {
+ monitor_printf(mon, "capabilities: ");
+ for (cap = params->capabilities; cap; cap = cap->next) {
+ monitor_printf(mon, "%s: %s ",
+ MigrationCapability_lookup[cap->value->capability],
+ cap->value->state ? "on" : "off");
+ }
+ monitor_printf(mon, "\n");
+ }
+
+ qapi_free_MigrationParameters(params);
+}
+
void hmp_info_cpus(Monitor *mon)
{
CpuInfoList *cpu_list, *cpu;
@@ -754,6 +790,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;
+ MigrationCapabilityStatusList *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_MigrationCapabilityStatusList(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 2fb44ca..ceb2f06 100644
--- a/hmp.h
+++ b/hmp.h
@@ -26,6 +26,7 @@ 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_migrate_parameters(Monitor *mon);
void hmp_info_cpus(Monitor *mon);
void hmp_info_block(Monitor *mon);
void hmp_info_blockstats(Monitor *mon);
@@ -52,6 +53,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 8c27347..e844290 100644
--- a/migration.c
+++ b/migration.c
@@ -113,6 +113,25 @@ uint64_t migrate_max_downtime(void)
return max_downtime;
}
+MigrationParameters *qmp_query_migrate_parameters(Error **errp)
+{
+ MigrationParameters *params = g_malloc0(sizeof(*params));
+ MigrationState *s = migrate_get_current();
+ int i;
+
+ params->capabilities = g_malloc0(sizeof(*params->capabilities));
+
+ for (i = 0; i < MIGRATION_CAPABILITY_MAX; i++) {
+ params->capabilities->value =
+ g_malloc(sizeof(*params->capabilities->value));
+ params->capabilities->value->capability = i;
+ params->capabilities->value->state = s->enabled_capabilities[i];
+ params->capabilities->next = NULL;
+ }
+
+ return params;
+}
+
MigrationInfo *qmp_query_migrate(Error **errp)
{
MigrationInfo *info = g_malloc0(sizeof(*info));
@@ -177,6 +196,22 @@ MigrationCapabilityStatusList *qmp_query_migration_capabilities(Error **errp)
return caps_list;
}
+void qmp_migrate_set_parameters(MigrationCapabilityStatusList *params,
+ Error **errp)
+{
+ MigrationState *s = migrate_get_current();
+ MigrationCapabilityStatusList *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)
@@ -386,12 +421,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;
s->total_time = qemu_get_clock_ms(rt_clock);
diff --git a/migration.h b/migration.h
index 57572a6..713aae0 100644
--- a/migration.h
+++ b/migration.h
@@ -19,6 +19,7 @@
#include "notify.h"
#include "error.h"
#include "vmstate.h"
+#include "qapi-types.h"
struct MigrationParams {
bool blk;
@@ -39,6 +40,7 @@ struct MigrationState
void *opaque;
MigrationParams params;
int64_t total_time;
+ bool enabled_capabilities[MIGRATION_CAPABILITY_MAX];
};
void process_incoming_migration(QEMUFile *f);
diff --git a/monitor.c b/monitor.c
index fd57c5e..e07af97 100644
--- a/monitor.c
+++ b/monitor.c
@@ -2669,6 +2669,13 @@ static mon_cmd_t info_cmds[] = {
.mhandler.info = hmp_info_migration_capabilities,
},
{
+ .name = "migrate-parameters",
+ .args_type = "",
+ .params = "",
+ .help = "show current migration parameters",
+ .mhandler.info = hmp_info_migrate_parameters,
+ },
+ {
.name = "balloon",
.args_type = "",
.params = "",
diff --git a/qapi-schema.json b/qapi-schema.json
index b4d4dd6..9d6759d 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -345,6 +345,38 @@
{ 'command': 'query-migration-capabilities', 'returns': ['MigrationCapabilityStatus'] }
##
+# @migrate-set-parameters
+#
+# Enable/Disable the following migration capabilities (like xbzrle)
+#
+# Since: 1.2
+##
+{ 'command': 'migrate-set-parameters',
+ 'data': { 'capabilities': ['MigrationCapabilityStatus'] } }
+
+##
+# @MigrationParameters
+#
+# @capabilities: @MigrationCapabilityStatus list contain current migration
+# capabilities status
+# Since: 1.2
+##
+{ 'type': 'MigrationParameters',
+ 'data': {'capabilities': ['MigrationCapabilityStatus']} }
+
+
+##
+# @query-migrate-parameters
+#
+# Returns information about the current migration capabilities status
+#
+# Returns: @MigrationParameters
+#
+# Since: 1.2
+##
+{ 'command': 'query-migrate-parameters', 'returns': 'MigrationParameters' }
+
+##
# @MouseInfo:
#
# Information about a mouse device.
diff --git a/qmp-commands.hx b/qmp-commands.hx
index c0ed14c..7f40e2a 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -2081,7 +2081,6 @@ The main json-object contains the following:
- "transferred": amount transferred (json-int)
- "remaining": amount remaining (json-int)
- "total": total (json-int)
-
Examples:
1. Before the first migration
@@ -2092,7 +2091,15 @@ Examples:
2. Migration is done and has succeeded
-> { "execute": "query-migrate" }
-<- { "return": { "status": "completed" } }
+<- { "return": {
+ "status": "completed",
+ "ram":{
+ "transferred":123,
+ "remaining":123,
+ "total":246
+ }
+ }
+ }
3. Migration is done and has failed
@@ -2165,6 +2172,55 @@ EQMP
},
SQMP
+migrate-set-parameters
+-------
+
+Enable/Disable 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-migrate-parameters
+-------
+
+Query current migration parameters
+
+- "capabilities": migration capabilities state
+ - "xbzrle" : XBZRLE state (json-bool)
+
+Arguments:
+
+Example:
+
+-> { "execute": "query-migrate-parameters" }
+<- { "return": {
+ "capabilities" : [ { "capability" : "xbzrle", "state" : false } ]
+ }
+ }
+EQMP
+
+ {
+ .name = "query-migrate-parameters",
+ .args_type = "",
+ .mhandler.cmd_new = qmp_marshal_input_query_migrate_parameters,
+ },
+
+SQMP
query-balloon
-------------
--
1.7.7.6
^ permalink raw reply related [flat|nested] 32+ messages in thread
* Re: [Qemu-devel] [PATCH 02/11] Add migrate_set_parameter and query-migrate-parameters
2012-07-29 9:42 ` [Qemu-devel] [PATCH 02/11] Add migrate_set_parameter and query-migrate-parameters Orit Wasserman
@ 2012-07-30 17:41 ` Luiz Capitulino
2012-07-31 7:46 ` Orit Wasserman
2012-07-31 8:03 ` Orit Wasserman
2012-07-30 18:11 ` Eric Blake
` (2 subsequent siblings)
3 siblings, 2 replies; 32+ messages in thread
From: Luiz Capitulino @ 2012-07-30 17:41 UTC (permalink / raw)
To: Orit Wasserman
Cc: peter.maydell, aliguori, quintela, stefanha, qemu-devel, mdroth,
blauwirbel, chegu_vinod, avi, pbonzini, eblake
On Sun, 29 Jul 2012 12:42:54 +0300
Orit Wasserman <owasserm@redhat.com> wrote:
> The management can enable/disable a capability for the next migration by using
> migrate_set_parameter command.
> The management can query the current migration capabilities using
> query-migrate-parameters
In general looks good to me, I have a question and a few nitpick comments
below.
>
> Signed-off-by: Orit Wasserman <owasserm@redhat.com>
> Signed-off-by: Juan Quintela <quintela@redhat.com>
> ---
> hmp-commands.hx | 16 ++++++++++++
> hmp.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
> hmp.h | 2 +
> migration.c | 42 +++++++++++++++++++++++++++++++-
> migration.h | 2 +
> monitor.c | 7 +++++
> qapi-schema.json | 32 ++++++++++++++++++++++++
> qmp-commands.hx | 60 ++++++++++++++++++++++++++++++++++++++++++++-
> 8 files changed, 229 insertions(+), 3 deletions(-)
>
> diff --git a/hmp-commands.hx b/hmp-commands.hx
> index 8786148..3e15338 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 = "capability state",
> + .help = "Enable/Disable 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 user network stack connection states
> show migration status
> @item info migration_capabilities
> show migration capabilities
> +@item info migrate_parameters
> +show current migration parameters
> @item info balloon
> show balloon information
> @item info qtree
> diff --git a/hmp.c b/hmp.c
> index 5c7d0be..f2f63fd 100644
> --- a/hmp.c
> +++ b/hmp.c
> @@ -131,8 +131,22 @@ void hmp_info_mice(Monitor *mon)
> void hmp_info_migrate(Monitor *mon)
> {
> MigrationInfo *info;
> + MigrationCapabilityStatusList *cap;
> + MigrationParameters *params;
>
> info = qmp_query_migrate(NULL);
> + params = qmp_query_migrate_parameters(NULL);
> +
> + /* do not display parameters during setup */
> + if (info->has_status && params->capabilities) {
> + monitor_printf(mon, "capabilities: ");
> + for (cap = params->capabilities; 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 +173,7 @@ void hmp_info_migrate(Monitor *mon)
> }
>
> qapi_free_MigrationInfo(info);
> + qapi_free_MigrationParameters(params);
> }
>
> void hmp_info_migration_capabilities(Monitor *mon)
> @@ -180,6 +195,27 @@ void hmp_info_migration_capabilities(Monitor *mon)
> qapi_free_MigrationCapabilityStatusList(caps_list);
> }
>
> +void hmp_info_migrate_parameters(Monitor *mon)
> +{
> +
> + MigrationCapabilityStatusList *cap;
> + MigrationParameters *params;
> +
> + params = qmp_query_migrate_parameters(NULL);
> +
> + if (params->capabilities) {
> + monitor_printf(mon, "capabilities: ");
> + for (cap = params->capabilities; cap; cap = cap->next) {
> + monitor_printf(mon, "%s: %s ",
> + MigrationCapability_lookup[cap->value->capability],
> + cap->value->state ? "on" : "off");
> + }
> + monitor_printf(mon, "\n");
> + }
> +
> + qapi_free_MigrationParameters(params);
> +}
> +
> void hmp_info_cpus(Monitor *mon)
> {
> CpuInfoList *cpu_list, *cpu;
> @@ -754,6 +790,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;
> + MigrationCapabilityStatusList *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));
> + }
This if shouldn't be necessary, right?
> + params->value = g_malloc0(sizeof(*params->value));
> + params->value->capability = i;
> + params->value->state = state;
> + params->next = NULL;
nitpick: I'd make the code ready for future capabilities.
> + qmp_migrate_set_parameters(params, &err);
> + break;
> + }
> + }
> +
> + if (i == MIGRATION_CAPABILITY_MAX) {
> + error_set(&err, QERR_INVALID_PARAMETER, cap);
> + }
> +
> + qapi_free_MigrationCapabilityStatusList(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 2fb44ca..ceb2f06 100644
> --- a/hmp.h
> +++ b/hmp.h
> @@ -26,6 +26,7 @@ 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_migrate_parameters(Monitor *mon);
> void hmp_info_cpus(Monitor *mon);
> void hmp_info_block(Monitor *mon);
> void hmp_info_blockstats(Monitor *mon);
> @@ -52,6 +53,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 8c27347..e844290 100644
> --- a/migration.c
> +++ b/migration.c
> @@ -113,6 +113,25 @@ uint64_t migrate_max_downtime(void)
> return max_downtime;
> }
>
> +MigrationParameters *qmp_query_migrate_parameters(Error **errp)
> +{
> + MigrationParameters *params = g_malloc0(sizeof(*params));
> + MigrationState *s = migrate_get_current();
> + int i;
> +
> + params->capabilities = g_malloc0(sizeof(*params->capabilities));
> +
> + for (i = 0; i < MIGRATION_CAPABILITY_MAX; i++) {
> + params->capabilities->value =
> + g_malloc(sizeof(*params->capabilities->value));
> + params->capabilities->value->capability = i;
> + params->capabilities->value->state = s->enabled_capabilities[i];
> + params->capabilities->next = NULL;
> + }
> +
> + return params;
> +}
> +
> MigrationInfo *qmp_query_migrate(Error **errp)
> {
> MigrationInfo *info = g_malloc0(sizeof(*info));
> @@ -177,6 +196,22 @@ MigrationCapabilityStatusList *qmp_query_migration_capabilities(Error **errp)
> return caps_list;
> }
>
> +void qmp_migrate_set_parameters(MigrationCapabilityStatusList *params,
> + Error **errp)
> +{
> + MigrationState *s = migrate_get_current();
> + MigrationCapabilityStatusList *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)
> @@ -386,12 +421,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));
Is s->enabled_capabilities initialized somewhere or are we making xbzrle
disabled by default?
>
> 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;
Unrelated change.
> s->state = MIG_STATE_SETUP;
> s->total_time = qemu_get_clock_ms(rt_clock);
>
> diff --git a/migration.h b/migration.h
> index 57572a6..713aae0 100644
> --- a/migration.h
> +++ b/migration.h
> @@ -19,6 +19,7 @@
> #include "notify.h"
> #include "error.h"
> #include "vmstate.h"
> +#include "qapi-types.h"
>
> struct MigrationParams {
> bool blk;
> @@ -39,6 +40,7 @@ struct MigrationState
> void *opaque;
> MigrationParams params;
> int64_t total_time;
> + bool enabled_capabilities[MIGRATION_CAPABILITY_MAX];
> };
>
> void process_incoming_migration(QEMUFile *f);
> diff --git a/monitor.c b/monitor.c
> index fd57c5e..e07af97 100644
> --- a/monitor.c
> +++ b/monitor.c
> @@ -2669,6 +2669,13 @@ static mon_cmd_t info_cmds[] = {
> .mhandler.info = hmp_info_migration_capabilities,
> },
> {
> + .name = "migrate-parameters",
> + .args_type = "",
> + .params = "",
> + .help = "show current migration parameters",
> + .mhandler.info = hmp_info_migrate_parameters,
> + },
> + {
> .name = "balloon",
> .args_type = "",
> .params = "",
> diff --git a/qapi-schema.json b/qapi-schema.json
> index b4d4dd6..9d6759d 100644
> --- a/qapi-schema.json
> +++ b/qapi-schema.json
> @@ -345,6 +345,38 @@
> { 'command': 'query-migration-capabilities', 'returns': ['MigrationCapabilityStatus'] }
>
> ##
> +# @migrate-set-parameters
> +#
> +# Enable/Disable the following migration capabilities (like xbzrle)
> +#
> +# Since: 1.2
> +##
> +{ 'command': 'migrate-set-parameters',
> + 'data': { 'capabilities': ['MigrationCapabilityStatus'] } }
> +
> +##
> +# @MigrationParameters
> +#
> +# @capabilities: @MigrationCapabilityStatus list contain current migration
> +# capabilities status
> +# Since: 1.2
> +##
> +{ 'type': 'MigrationParameters',
> + 'data': {'capabilities': ['MigrationCapabilityStatus']} }
> +
> +
> +##
> +# @query-migrate-parameters
> +#
> +# Returns information about the current migration capabilities status
> +#
> +# Returns: @MigrationParameters
> +#
> +# Since: 1.2
> +##
> +{ 'command': 'query-migrate-parameters', 'returns': 'MigrationParameters' }
> +
> +##
> # @MouseInfo:
> #
> # Information about a mouse device.
> diff --git a/qmp-commands.hx b/qmp-commands.hx
> index c0ed14c..7f40e2a 100644
> --- a/qmp-commands.hx
> +++ b/qmp-commands.hx
> @@ -2081,7 +2081,6 @@ The main json-object contains the following:
> - "transferred": amount transferred (json-int)
> - "remaining": amount remaining (json-int)
> - "total": total (json-int)
> -
> Examples:
>
> 1. Before the first migration
> @@ -2092,7 +2091,15 @@ Examples:
> 2. Migration is done and has succeeded
>
> -> { "execute": "query-migrate" }
> -<- { "return": { "status": "completed" } }
> +<- { "return": {
> + "status": "completed",
> + "ram":{
> + "transferred":123,
> + "remaining":123,
> + "total":246
> + }
> + }
> + }
>
> 3. Migration is done and has failed
>
> @@ -2165,6 +2172,55 @@ EQMP
> },
>
> SQMP
> +migrate-set-parameters
> +-------
> +
> +Enable/Disable 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-migrate-parameters
> +-------
> +
> +Query current migration parameters
> +
> +- "capabilities": migration capabilities state
> + - "xbzrle" : XBZRLE state (json-bool)
> +
> +Arguments:
> +
> +Example:
> +
> +-> { "execute": "query-migrate-parameters" }
> +<- { "return": {
> + "capabilities" : [ { "capability" : "xbzrle", "state" : false } ]
> + }
> + }
> +EQMP
> +
> + {
> + .name = "query-migrate-parameters",
> + .args_type = "",
> + .mhandler.cmd_new = qmp_marshal_input_query_migrate_parameters,
> + },
> +
> +SQMP
> query-balloon
> -------------
>
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Qemu-devel] [PATCH 02/11] Add migrate_set_parameter and query-migrate-parameters
2012-07-29 9:42 ` [Qemu-devel] [PATCH 02/11] Add migrate_set_parameter and query-migrate-parameters Orit Wasserman
2012-07-30 17:41 ` Luiz Capitulino
@ 2012-07-30 18:11 ` Eric Blake
2012-07-30 18:15 ` Luiz Capitulino
2012-07-30 19:12 ` Juan Quintela
2012-07-30 19:45 ` Anthony Liguori
3 siblings, 1 reply; 32+ messages in thread
From: Eric Blake @ 2012-07-30 18:11 UTC (permalink / raw)
To: Orit Wasserman
Cc: peter.maydell, aliguori, quintela, stefanha, qemu-devel, mdroth,
blauwirbel, avi, pbonzini, lcapitulino, chegu_vinod
[-- Attachment #1: Type: text/plain, Size: 1663 bytes --]
On 07/29/2012 03:42 AM, Orit Wasserman wrote:
> The management can enable/disable a capability for the next migration by using
> migrate_set_parameter command.
> The management can query the current migration capabilities using
> query-migrate-parameters
In addition to Luiz' nitpicks:
Here in the commit message, you are mixing HMP (migrate_set_parameter)
with QMP (query-migrate-parameters). It might be better to stick to HMP
only (migrate_set_parameter, info migrate_parameters) or QMP only
(migrate-set-parameter, query-migrate-parameters), or even list the
spellings for both protocols.
> +++ b/hmp-commands.hx
> @@ -1419,6 +1433,8 @@ show user network stack connection states
> show migration status
> @item info migration_capabilities
> show migration capabilities
> +@item info migrate_parameters
> +show current migration parameters
> +++ b/monitor.c
> @@ -2669,6 +2669,13 @@ static mon_cmd_t info_cmds[] = {
> .mhandler.info = hmp_info_migration_capabilities,
> },
> {
> + .name = "migrate-parameters",
Is this the correct spelling? Or is this feeding the HMP interface,
where you documented it above as 'info migrate_parameters'?
> +++ b/qapi-schema.json
> @@ -345,6 +345,38 @@
> { 'command': 'query-migration-capabilities', 'returns': ['MigrationCapabilityStatus'] }
>
> ##
> +# @migrate-set-parameters
> +#
> +# Enable/Disable the following migration capabilities (like xbzrle)
> +#
> +# Since: 1.2
Same comment as in 1/11 about 1.2 vs. 1.2.0.
--
Eric Blake eblake@redhat.com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 620 bytes --]
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Qemu-devel] [PATCH 02/11] Add migrate_set_parameter and query-migrate-parameters
2012-07-30 18:11 ` Eric Blake
@ 2012-07-30 18:15 ` Luiz Capitulino
0 siblings, 0 replies; 32+ messages in thread
From: Luiz Capitulino @ 2012-07-30 18:15 UTC (permalink / raw)
To: Eric Blake
Cc: peter.maydell, aliguori, quintela, stefanha, qemu-devel, mdroth,
blauwirbel, Orit Wasserman, avi, pbonzini, chegu_vinod
On Mon, 30 Jul 2012 12:11:52 -0600
Eric Blake <eblake@redhat.com> wrote:
> On 07/29/2012 03:42 AM, Orit Wasserman wrote:
> > The management can enable/disable a capability for the next migration by using
> > migrate_set_parameter command.
> > The management can query the current migration capabilities using
> > query-migrate-parameters
>
> In addition to Luiz' nitpicks:
>
> Here in the commit message, you are mixing HMP (migrate_set_parameter)
> with QMP (query-migrate-parameters). It might be better to stick to HMP
> only (migrate_set_parameter, info migrate_parameters) or QMP only
> (migrate-set-parameter, query-migrate-parameters), or even list the
> spellings for both protocols.
>
> > +++ b/hmp-commands.hx
>
> > @@ -1419,6 +1433,8 @@ show user network stack connection states
> > show migration status
> > @item info migration_capabilities
> > show migration capabilities
> > +@item info migrate_parameters
> > +show current migration parameters
>
> > +++ b/monitor.c
> > @@ -2669,6 +2669,13 @@ static mon_cmd_t info_cmds[] = {
> > .mhandler.info = hmp_info_migration_capabilities,
> > },
> > {
> > + .name = "migrate-parameters",
>
> Is this the correct spelling? Or is this feeding the HMP interface,
> where you documented it above as 'info migrate_parameters'?
It's the HMP interface, yes.
>
> > +++ b/qapi-schema.json
> > @@ -345,6 +345,38 @@
> > { 'command': 'query-migration-capabilities', 'returns': ['MigrationCapabilityStatus'] }
> >
> > ##
> > +# @migrate-set-parameters
> > +#
> > +# Enable/Disable the following migration capabilities (like xbzrle)
> > +#
> > +# Since: 1.2
>
> Same comment as in 1/11 about 1.2 vs. 1.2.0.
>
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Qemu-devel] [PATCH 02/11] Add migrate_set_parameter and query-migrate-parameters
2012-07-29 9:42 ` [Qemu-devel] [PATCH 02/11] Add migrate_set_parameter and query-migrate-parameters Orit Wasserman
2012-07-30 17:41 ` Luiz Capitulino
2012-07-30 18:11 ` Eric Blake
@ 2012-07-30 19:12 ` Juan Quintela
2012-07-30 19:24 ` Eric Blake
` (2 more replies)
2012-07-30 19:45 ` Anthony Liguori
3 siblings, 3 replies; 32+ messages in thread
From: Juan Quintela @ 2012-07-30 19:12 UTC (permalink / raw)
To: Orit Wasserman
Cc: peter.maydell, aliguori, stefanha, qemu-devel, mdroth, blauwirbel,
chegu_vinod, avi, pbonzini, lcapitulino, eblake
Orit Wasserman <owasserm@redhat.com> wrote:
> The management can enable/disable a capability for the next migration by using
> migrate_set_parameter command.
> The management can query the current migration capabilities using
> query-migrate-parameters
>
> Signed-off-by: Orit Wasserman <owasserm@redhat.com>
> Signed-off-by: Juan Quintela <quintela@redhat.com>
I just noticed .... shouldn't we use
migrate_set_parameter cache_size 256M
???
I think that even the old migration parameters could be added to this
one?
migrate_set_parameter downtime 30ms
migrate_set_parameter bandwidth 1G
This way everything would be more regular, and easier on libvirt, as new
parameters would be trivial to ask for?
Notice that I can understand that we have to maintain the old commands
for compability, but we can do "regularly" for new ones?
Later, Juan.
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Qemu-devel] [PATCH 02/11] Add migrate_set_parameter and query-migrate-parameters
2012-07-30 19:12 ` Juan Quintela
@ 2012-07-30 19:24 ` Eric Blake
2012-07-30 19:37 ` Anthony Liguori
2012-07-30 20:21 ` Juan Quintela
2 siblings, 0 replies; 32+ messages in thread
From: Eric Blake @ 2012-07-30 19:24 UTC (permalink / raw)
To: quintela
Cc: peter.maydell, aliguori, stefanha, qemu-devel, mdroth, blauwirbel,
Orit Wasserman, avi, pbonzini, lcapitulino, chegu_vinod
[-- Attachment #1: Type: text/plain, Size: 1410 bytes --]
On 07/30/2012 01:12 PM, Juan Quintela wrote:
> Orit Wasserman <owasserm@redhat.com> wrote:
>> The management can enable/disable a capability for the next migration by using
>> migrate_set_parameter command.
>> The management can query the current migration capabilities using
>> query-migrate-parameters
>>
>> Signed-off-by: Orit Wasserman <owasserm@redhat.com>
>> Signed-off-by: Juan Quintela <quintela@redhat.com>
>
> I just noticed .... shouldn't we use
>
> migrate_set_parameter cache_size 256M
> ???
>
> I think that even the old migration parameters could be added to this
> one?
>
> migrate_set_parameter downtime 30ms
> migrate_set_parameter bandwidth 1G
The existing patch was written under the assumption that parameters were
only ever bool; but you are proposing allowing non-bool parameters.
>
> This way everything would be more regular, and easier on libvirt, as new
> parameters would be trivial to ask for?
That depends on the QMP interface you come up with for expressing
non-bool parameters. This patch series has already been churning for
several months now, which makes it feel a bit late to be changing the
interface to support non-bool parameters, unless we really like the idea
and can afford another delay in getting this series in.
--
Eric Blake eblake@redhat.com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 620 bytes --]
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Qemu-devel] [PATCH 02/11] Add migrate_set_parameter and query-migrate-parameters
2012-07-30 19:12 ` Juan Quintela
2012-07-30 19:24 ` Eric Blake
@ 2012-07-30 19:37 ` Anthony Liguori
2012-07-30 20:21 ` Juan Quintela
2 siblings, 0 replies; 32+ messages in thread
From: Anthony Liguori @ 2012-07-30 19:37 UTC (permalink / raw)
To: quintela, Orit Wasserman
Cc: peter.maydell, stefanha, mdroth, qemu-devel, blauwirbel,
chegu_vinod, avi, pbonzini, lcapitulino, eblake
Juan Quintela <quintela@redhat.com> writes:
> Orit Wasserman <owasserm@redhat.com> wrote:
>> The management can enable/disable a capability for the next migration by using
>> migrate_set_parameter command.
>> The management can query the current migration capabilities using
>> query-migrate-parameters
>>
>> Signed-off-by: Orit Wasserman <owasserm@redhat.com>
>> Signed-off-by: Juan Quintela <quintela@redhat.com>
>
> I just noticed .... shouldn't we use
>
> migrate_set_parameter cache_size 256M
> ???
>
> I think that even the old migration parameters could be added to this
> one?
>
> migrate_set_parameter downtime 30ms
> migrate_set_parameter bandwidth 1G
>
> This way everything would be more regular, and easier on libvirt, as new
> parameters would be trivial to ask for?
>
> Notice that I can understand that we have to maintain the old commands
> for compability, but we can do "regularly" for new ones?
I think this is worse. How does libvirt determine which parameters are
valid?
Let's do migrate_set_cache_size. Please don't introduce commands that
multiplex multiple behavior. They do more harm than good.
Regards,
Anthony Liguori
>
> Later, Juan.
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Qemu-devel] [PATCH 02/11] Add migrate_set_parameter and query-migrate-parameters
2012-07-29 9:42 ` [Qemu-devel] [PATCH 02/11] Add migrate_set_parameter and query-migrate-parameters Orit Wasserman
` (2 preceding siblings ...)
2012-07-30 19:12 ` Juan Quintela
@ 2012-07-30 19:45 ` Anthony Liguori
2012-07-30 19:58 ` Luiz Capitulino
3 siblings, 1 reply; 32+ messages in thread
From: Anthony Liguori @ 2012-07-30 19:45 UTC (permalink / raw)
To: Orit Wasserman, qemu-devel
Cc: peter.maydell, quintela, stefanha, mdroth, lcapitulino,
blauwirbel, chegu_vinod, avi, pbonzini, eblake
Orit Wasserman <owasserm@redhat.com> writes:
> The management can enable/disable a capability for the next migration by using
> migrate_set_parameter command.
> The management can query the current migration capabilities using
> query-migrate-parameters
>
> Signed-off-by: Orit Wasserman <owasserm@redhat.com>
> Signed-off-by: Juan Quintela <quintela@redhat.com>
We have a way to add new commands. Let's not invent a new one.
Otherwise every subsystem would have it's own approach to querying
what's available.
Regards,
Anthony Liguori
> ---
> hmp-commands.hx | 16 ++++++++++++
> hmp.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
> hmp.h | 2 +
> migration.c | 42 +++++++++++++++++++++++++++++++-
> migration.h | 2 +
> monitor.c | 7 +++++
> qapi-schema.json | 32 ++++++++++++++++++++++++
> qmp-commands.hx | 60 ++++++++++++++++++++++++++++++++++++++++++++-
> 8 files changed, 229 insertions(+), 3 deletions(-)
>
> diff --git a/hmp-commands.hx b/hmp-commands.hx
> index 8786148..3e15338 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 = "capability state",
> + .help = "Enable/Disable 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 user network stack connection states
> show migration status
> @item info migration_capabilities
> show migration capabilities
> +@item info migrate_parameters
> +show current migration parameters
> @item info balloon
> show balloon information
> @item info qtree
> diff --git a/hmp.c b/hmp.c
> index 5c7d0be..f2f63fd 100644
> --- a/hmp.c
> +++ b/hmp.c
> @@ -131,8 +131,22 @@ void hmp_info_mice(Monitor *mon)
> void hmp_info_migrate(Monitor *mon)
> {
> MigrationInfo *info;
> + MigrationCapabilityStatusList *cap;
> + MigrationParameters *params;
>
> info = qmp_query_migrate(NULL);
> + params = qmp_query_migrate_parameters(NULL);
> +
> + /* do not display parameters during setup */
> + if (info->has_status && params->capabilities) {
> + monitor_printf(mon, "capabilities: ");
> + for (cap = params->capabilities; 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 +173,7 @@ void hmp_info_migrate(Monitor *mon)
> }
>
> qapi_free_MigrationInfo(info);
> + qapi_free_MigrationParameters(params);
> }
>
> void hmp_info_migration_capabilities(Monitor *mon)
> @@ -180,6 +195,27 @@ void hmp_info_migration_capabilities(Monitor *mon)
> qapi_free_MigrationCapabilityStatusList(caps_list);
> }
>
> +void hmp_info_migrate_parameters(Monitor *mon)
> +{
> +
> + MigrationCapabilityStatusList *cap;
> + MigrationParameters *params;
> +
> + params = qmp_query_migrate_parameters(NULL);
> +
> + if (params->capabilities) {
> + monitor_printf(mon, "capabilities: ");
> + for (cap = params->capabilities; cap; cap = cap->next) {
> + monitor_printf(mon, "%s: %s ",
> + MigrationCapability_lookup[cap->value->capability],
> + cap->value->state ? "on" : "off");
> + }
> + monitor_printf(mon, "\n");
> + }
> +
> + qapi_free_MigrationParameters(params);
> +}
> +
> void hmp_info_cpus(Monitor *mon)
> {
> CpuInfoList *cpu_list, *cpu;
> @@ -754,6 +790,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;
> + MigrationCapabilityStatusList *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_MigrationCapabilityStatusList(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 2fb44ca..ceb2f06 100644
> --- a/hmp.h
> +++ b/hmp.h
> @@ -26,6 +26,7 @@ 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_migrate_parameters(Monitor *mon);
> void hmp_info_cpus(Monitor *mon);
> void hmp_info_block(Monitor *mon);
> void hmp_info_blockstats(Monitor *mon);
> @@ -52,6 +53,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 8c27347..e844290 100644
> --- a/migration.c
> +++ b/migration.c
> @@ -113,6 +113,25 @@ uint64_t migrate_max_downtime(void)
> return max_downtime;
> }
>
> +MigrationParameters *qmp_query_migrate_parameters(Error **errp)
> +{
> + MigrationParameters *params = g_malloc0(sizeof(*params));
> + MigrationState *s = migrate_get_current();
> + int i;
> +
> + params->capabilities = g_malloc0(sizeof(*params->capabilities));
> +
> + for (i = 0; i < MIGRATION_CAPABILITY_MAX; i++) {
> + params->capabilities->value =
> + g_malloc(sizeof(*params->capabilities->value));
> + params->capabilities->value->capability = i;
> + params->capabilities->value->state = s->enabled_capabilities[i];
> + params->capabilities->next = NULL;
> + }
> +
> + return params;
> +}
> +
> MigrationInfo *qmp_query_migrate(Error **errp)
> {
> MigrationInfo *info = g_malloc0(sizeof(*info));
> @@ -177,6 +196,22 @@ MigrationCapabilityStatusList *qmp_query_migration_capabilities(Error **errp)
> return caps_list;
> }
>
> +void qmp_migrate_set_parameters(MigrationCapabilityStatusList *params,
> + Error **errp)
> +{
> + MigrationState *s = migrate_get_current();
> + MigrationCapabilityStatusList *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)
> @@ -386,12 +421,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;
> s->total_time = qemu_get_clock_ms(rt_clock);
>
> diff --git a/migration.h b/migration.h
> index 57572a6..713aae0 100644
> --- a/migration.h
> +++ b/migration.h
> @@ -19,6 +19,7 @@
> #include "notify.h"
> #include "error.h"
> #include "vmstate.h"
> +#include "qapi-types.h"
>
> struct MigrationParams {
> bool blk;
> @@ -39,6 +40,7 @@ struct MigrationState
> void *opaque;
> MigrationParams params;
> int64_t total_time;
> + bool enabled_capabilities[MIGRATION_CAPABILITY_MAX];
> };
>
> void process_incoming_migration(QEMUFile *f);
> diff --git a/monitor.c b/monitor.c
> index fd57c5e..e07af97 100644
> --- a/monitor.c
> +++ b/monitor.c
> @@ -2669,6 +2669,13 @@ static mon_cmd_t info_cmds[] = {
> .mhandler.info = hmp_info_migration_capabilities,
> },
> {
> + .name = "migrate-parameters",
> + .args_type = "",
> + .params = "",
> + .help = "show current migration parameters",
> + .mhandler.info = hmp_info_migrate_parameters,
> + },
> + {
> .name = "balloon",
> .args_type = "",
> .params = "",
> diff --git a/qapi-schema.json b/qapi-schema.json
> index b4d4dd6..9d6759d 100644
> --- a/qapi-schema.json
> +++ b/qapi-schema.json
> @@ -345,6 +345,38 @@
> { 'command': 'query-migration-capabilities', 'returns': ['MigrationCapabilityStatus'] }
>
> ##
> +# @migrate-set-parameters
> +#
> +# Enable/Disable the following migration capabilities (like xbzrle)
> +#
> +# Since: 1.2
> +##
> +{ 'command': 'migrate-set-parameters',
> + 'data': { 'capabilities': ['MigrationCapabilityStatus'] } }
> +
> +##
> +# @MigrationParameters
> +#
> +# @capabilities: @MigrationCapabilityStatus list contain current migration
> +# capabilities status
> +# Since: 1.2
> +##
> +{ 'type': 'MigrationParameters',
> + 'data': {'capabilities': ['MigrationCapabilityStatus']} }
> +
> +
> +##
> +# @query-migrate-parameters
> +#
> +# Returns information about the current migration capabilities status
> +#
> +# Returns: @MigrationParameters
> +#
> +# Since: 1.2
> +##
> +{ 'command': 'query-migrate-parameters', 'returns': 'MigrationParameters' }
> +
> +##
> # @MouseInfo:
> #
> # Information about a mouse device.
> diff --git a/qmp-commands.hx b/qmp-commands.hx
> index c0ed14c..7f40e2a 100644
> --- a/qmp-commands.hx
> +++ b/qmp-commands.hx
> @@ -2081,7 +2081,6 @@ The main json-object contains the following:
> - "transferred": amount transferred (json-int)
> - "remaining": amount remaining (json-int)
> - "total": total (json-int)
> -
> Examples:
>
> 1. Before the first migration
> @@ -2092,7 +2091,15 @@ Examples:
> 2. Migration is done and has succeeded
>
> -> { "execute": "query-migrate" }
> -<- { "return": { "status": "completed" } }
> +<- { "return": {
> + "status": "completed",
> + "ram":{
> + "transferred":123,
> + "remaining":123,
> + "total":246
> + }
> + }
> + }
>
> 3. Migration is done and has failed
>
> @@ -2165,6 +2172,55 @@ EQMP
> },
>
> SQMP
> +migrate-set-parameters
> +-------
> +
> +Enable/Disable 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-migrate-parameters
> +-------
> +
> +Query current migration parameters
> +
> +- "capabilities": migration capabilities state
> + - "xbzrle" : XBZRLE state (json-bool)
> +
> +Arguments:
> +
> +Example:
> +
> +-> { "execute": "query-migrate-parameters" }
> +<- { "return": {
> + "capabilities" : [ { "capability" : "xbzrle", "state" : false } ]
> + }
> + }
> +EQMP
> +
> + {
> + .name = "query-migrate-parameters",
> + .args_type = "",
> + .mhandler.cmd_new = qmp_marshal_input_query_migrate_parameters,
> + },
> +
> +SQMP
> query-balloon
> -------------
>
> --
> 1.7.7.6
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Qemu-devel] [PATCH 02/11] Add migrate_set_parameter and query-migrate-parameters
2012-07-30 19:45 ` Anthony Liguori
@ 2012-07-30 19:58 ` Luiz Capitulino
2012-07-30 20:04 ` Anthony Liguori
0 siblings, 1 reply; 32+ messages in thread
From: Luiz Capitulino @ 2012-07-30 19:58 UTC (permalink / raw)
To: Anthony Liguori
Cc: peter.maydell, quintela, stefanha, qemu-devel, mdroth, blauwirbel,
Orit Wasserman, chegu_vinod, avi, pbonzini, eblake
On Mon, 30 Jul 2012 14:45:04 -0500
Anthony Liguori <aliguori@us.ibm.com> wrote:
> Orit Wasserman <owasserm@redhat.com> writes:
>
> > The management can enable/disable a capability for the next migration by using
> > migrate_set_parameter command.
> > The management can query the current migration capabilities using
> > query-migrate-parameters
> >
> > Signed-off-by: Orit Wasserman <owasserm@redhat.com>
> > Signed-off-by: Juan Quintela <quintela@redhat.com>
>
> We have a way to add new commands. Let's not invent a new one.
> Otherwise every subsystem would have it's own approach to querying
> what's available.
I think it does make sense for setting/getting migration's capabilities, which
are just booleans. And that's what the commands currently do, btw.
I'd only recommend to rename them to migrate_set_capability
query-migrate-capabilities.
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Qemu-devel] [PATCH 02/11] Add migrate_set_parameter and query-migrate-parameters
2012-07-30 19:58 ` Luiz Capitulino
@ 2012-07-30 20:04 ` Anthony Liguori
2012-07-30 20:20 ` Luiz Capitulino
0 siblings, 1 reply; 32+ messages in thread
From: Anthony Liguori @ 2012-07-30 20:04 UTC (permalink / raw)
To: Luiz Capitulino
Cc: peter.maydell, quintela, stefanha, qemu-devel, mdroth, blauwirbel,
Orit Wasserman, chegu_vinod, avi, pbonzini, eblake
Luiz Capitulino <lcapitulino@redhat.com> writes:
> On Mon, 30 Jul 2012 14:45:04 -0500
> Anthony Liguori <aliguori@us.ibm.com> wrote:
>
>> Orit Wasserman <owasserm@redhat.com> writes:
>>
>> > The management can enable/disable a capability for the next migration by using
>> > migrate_set_parameter command.
>> > The management can query the current migration capabilities using
>> > query-migrate-parameters
>> >
>> > Signed-off-by: Orit Wasserman <owasserm@redhat.com>
>> > Signed-off-by: Juan Quintela <quintela@redhat.com>
>>
>> We have a way to add new commands. Let's not invent a new one.
>> Otherwise every subsystem would have it's own approach to querying
>> what's available.
>
> I think it does make sense for setting/getting migration's capabilities, which
> are just booleans. And that's what the commands currently do, btw.
>
> I'd only recommend to rename them to migrate_set_capability
> query-migrate-capabilities.
If that's the intent, it should take/return a list of capabilities
(expressed as an enum).
Regards,
Anthony Liguori
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Qemu-devel] [PATCH 02/11] Add migrate_set_parameter and query-migrate-parameters
2012-07-30 20:04 ` Anthony Liguori
@ 2012-07-30 20:20 ` Luiz Capitulino
0 siblings, 0 replies; 32+ messages in thread
From: Luiz Capitulino @ 2012-07-30 20:20 UTC (permalink / raw)
To: Anthony Liguori
Cc: peter.maydell, quintela, stefanha, qemu-devel, mdroth, blauwirbel,
Orit Wasserman, chegu_vinod, avi, pbonzini, eblake
On Mon, 30 Jul 2012 15:04:57 -0500
Anthony Liguori <aliguori@us.ibm.com> wrote:
> Luiz Capitulino <lcapitulino@redhat.com> writes:
>
> > On Mon, 30 Jul 2012 14:45:04 -0500
> > Anthony Liguori <aliguori@us.ibm.com> wrote:
> >
> >> Orit Wasserman <owasserm@redhat.com> writes:
> >>
> >> > The management can enable/disable a capability for the next migration by using
> >> > migrate_set_parameter command.
> >> > The management can query the current migration capabilities using
> >> > query-migrate-parameters
> >> >
> >> > Signed-off-by: Orit Wasserman <owasserm@redhat.com>
> >> > Signed-off-by: Juan Quintela <quintela@redhat.com>
> >>
> >> We have a way to add new commands. Let's not invent a new one.
> >> Otherwise every subsystem would have it's own approach to querying
> >> what's available.
> >
> > I think it does make sense for setting/getting migration's capabilities, which
> > are just booleans. And that's what the commands currently do, btw.
> >
> > I'd only recommend to rename them to migrate_set_capability
> > query-migrate-capabilities.
>
> If that's the intent, it should take/return a list of capabilities
> (expressed as an enum).
Yes, it already does it iirc.
Now, there's something I'm not sure about. This series adds three commands:
- migrate-set-parameter (should be renamed to migrate-set-capabilities)
- query-migrate-parameters (should be renamed to query-migrate-capabilities)
- query-migration-capabilities (should be dropped?)
That last command returns the supported capabilities. We should either,
rename it to query-migration-supported-capabilities or just drop it, because
if a capability appears in (this series') query-migrate-parameters it
means that the capability is supported.
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Qemu-devel] [PATCH 02/11] Add migrate_set_parameter and query-migrate-parameters
2012-07-30 19:12 ` Juan Quintela
2012-07-30 19:24 ` Eric Blake
2012-07-30 19:37 ` Anthony Liguori
@ 2012-07-30 20:21 ` Juan Quintela
2 siblings, 0 replies; 32+ messages in thread
From: Juan Quintela @ 2012-07-30 20:21 UTC (permalink / raw)
To: Orit Wasserman
Cc: peter.maydell, aliguori, stefanha, qemu-devel, mdroth, blauwirbel,
chegu_vinod, avi, pbonzini, lcapitulino, eblake
Juan Quintela <quintela@redhat.com> wrote:
> Orit Wasserman <owasserm@redhat.com> wrote:
>> The management can enable/disable a capability for the next migration by using
>> migrate_set_parameter command.
>> The management can query the current migration capabilities using
>> query-migrate-parameters
>>
>> Signed-off-by: Orit Wasserman <owasserm@redhat.com>
>> Signed-off-by: Juan Quintela <quintela@redhat.com>
>
> I just noticed .... shouldn't we use
>
> migrate_set_parameter cache_size 256M
> ???
>
> I think that even the old migration parameters could be added to this
> one?
>
> migrate_set_parameter downtime 30ms
> migrate_set_parameter bandwidth 1G
/me nacks myself. It appears that I am the only one that thinks that
command explosion is bad O;-)
(and yes, it is a different compromise.)
>
> This way everything would be more regular, and easier on libvirt, as new
> parameters would be trivial to ask for?
>
> Notice that I can understand that we have to maintain the old commands
> for compability, but we can do "regularly" for new ones?
>
> Later, Juan.
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Qemu-devel] [PATCH 02/11] Add migrate_set_parameter and query-migrate-parameters
2012-07-30 17:41 ` Luiz Capitulino
@ 2012-07-31 7:46 ` Orit Wasserman
2012-07-31 13:09 ` Luiz Capitulino
2012-07-31 8:03 ` Orit Wasserman
1 sibling, 1 reply; 32+ messages in thread
From: Orit Wasserman @ 2012-07-31 7:46 UTC (permalink / raw)
To: Luiz Capitulino
Cc: peter.maydell, aliguori, quintela, stefanha, qemu-devel, mdroth,
blauwirbel, chegu_vinod, avi, pbonzini, eblake
On 07/30/2012 08:41 PM, Luiz Capitulino wrote:
> On Sun, 29 Jul 2012 12:42:54 +0300
> Orit Wasserman <owasserm@redhat.com> wrote:
>
>> The management can enable/disable a capability for the next migration by using
>> migrate_set_parameter command.
>> The management can query the current migration capabilities using
>> query-migrate-parameters
>
> In general looks good to me, I have a question and a few nitpick comments
> below.
>
>>
>> Signed-off-by: Orit Wasserman <owasserm@redhat.com>
>> Signed-off-by: Juan Quintela <quintela@redhat.com>
>> ---
>> hmp-commands.hx | 16 ++++++++++++
>> hmp.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
>> hmp.h | 2 +
>> migration.c | 42 +++++++++++++++++++++++++++++++-
>> migration.h | 2 +
>> monitor.c | 7 +++++
>> qapi-schema.json | 32 ++++++++++++++++++++++++
>> qmp-commands.hx | 60 ++++++++++++++++++++++++++++++++++++++++++++-
>> 8 files changed, 229 insertions(+), 3 deletions(-)
>>
>> diff --git a/hmp-commands.hx b/hmp-commands.hx
>> index 8786148..3e15338 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 = "capability state",
>> + .help = "Enable/Disable 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 user network stack connection states
>> show migration status
>> @item info migration_capabilities
>> show migration capabilities
>> +@item info migrate_parameters
>> +show current migration parameters
>> @item info balloon
>> show balloon information
>> @item info qtree
>> diff --git a/hmp.c b/hmp.c
>> index 5c7d0be..f2f63fd 100644
>> --- a/hmp.c
>> +++ b/hmp.c
>> @@ -131,8 +131,22 @@ void hmp_info_mice(Monitor *mon)
>> void hmp_info_migrate(Monitor *mon)
>> {
>> MigrationInfo *info;
>> + MigrationCapabilityStatusList *cap;
>> + MigrationParameters *params;
>>
>> info = qmp_query_migrate(NULL);
>> + params = qmp_query_migrate_parameters(NULL);
>> +
>> + /* do not display parameters during setup */
>> + if (info->has_status && params->capabilities) {
>> + monitor_printf(mon, "capabilities: ");
>> + for (cap = params->capabilities; 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 +173,7 @@ void hmp_info_migrate(Monitor *mon)
>> }
>>
>> qapi_free_MigrationInfo(info);
>> + qapi_free_MigrationParameters(params);
>> }
>>
>> void hmp_info_migration_capabilities(Monitor *mon)
>> @@ -180,6 +195,27 @@ void hmp_info_migration_capabilities(Monitor *mon)
>> qapi_free_MigrationCapabilityStatusList(caps_list);
>> }
>>
>> +void hmp_info_migrate_parameters(Monitor *mon)
>> +{
>> +
>> + MigrationCapabilityStatusList *cap;
>> + MigrationParameters *params;
>> +
>> + params = qmp_query_migrate_parameters(NULL);
>> +
>> + if (params->capabilities) {
>> + monitor_printf(mon, "capabilities: ");
>> + for (cap = params->capabilities; cap; cap = cap->next) {
>> + monitor_printf(mon, "%s: %s ",
>> + MigrationCapability_lookup[cap->value->capability],
>> + cap->value->state ? "on" : "off");
>> + }
>> + monitor_printf(mon, "\n");
>> + }
>> +
>> + qapi_free_MigrationParameters(params);
>> +}
>> +
>> void hmp_info_cpus(Monitor *mon)
>> {
>> CpuInfoList *cpu_list, *cpu;
>> @@ -754,6 +790,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;
>> + MigrationCapabilityStatusList *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));
>> + }
>
> This if shouldn't be necessary, right?
You are right I can always allocate it.
>
>> + params->value = g_malloc0(sizeof(*params->value));
>> + params->value->capability = i;
>> + params->value->state = state;
>> + params->next = NULL;
>
> nitpick: I'd make the code ready for future capabilities.
Could you give me a bit more details ?
Orit
>
>> + qmp_migrate_set_parameters(params, &err);
>> + break;
>> + }
>> + }
>> +
>> + if (i == MIGRATION_CAPABILITY_MAX) {
>> + error_set(&err, QERR_INVALID_PARAMETER, cap);
>> + }
>> +
>> + qapi_free_MigrationCapabilityStatusList(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 2fb44ca..ceb2f06 100644
>> --- a/hmp.h
>> +++ b/hmp.h
>> @@ -26,6 +26,7 @@ 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_migrate_parameters(Monitor *mon);
>> void hmp_info_cpus(Monitor *mon);
>> void hmp_info_block(Monitor *mon);
>> void hmp_info_blockstats(Monitor *mon);
>> @@ -52,6 +53,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 8c27347..e844290 100644
>> --- a/migration.c
>> +++ b/migration.c
>> @@ -113,6 +113,25 @@ uint64_t migrate_max_downtime(void)
>> return max_downtime;
>> }
>>
>> +MigrationParameters *qmp_query_migrate_parameters(Error **errp)
>> +{
>> + MigrationParameters *params = g_malloc0(sizeof(*params));
>> + MigrationState *s = migrate_get_current();
>> + int i;
>> +
>> + params->capabilities = g_malloc0(sizeof(*params->capabilities));
>> +
>> + for (i = 0; i < MIGRATION_CAPABILITY_MAX; i++) {
>> + params->capabilities->value =
>> + g_malloc(sizeof(*params->capabilities->value));
>> + params->capabilities->value->capability = i;
>> + params->capabilities->value->state = s->enabled_capabilities[i];
>> + params->capabilities->next = NULL;
>> + }
>> +
>> + return params;
>> +}
>> +
>> MigrationInfo *qmp_query_migrate(Error **errp)
>> {
>> MigrationInfo *info = g_malloc0(sizeof(*info));
>> @@ -177,6 +196,22 @@ MigrationCapabilityStatusList *qmp_query_migration_capabilities(Error **errp)
>> return caps_list;
>> }
>>
>> +void qmp_migrate_set_parameters(MigrationCapabilityStatusList *params,
>> + Error **errp)
>> +{
>> + MigrationState *s = migrate_get_current();
>> + MigrationCapabilityStatusList *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)
>> @@ -386,12 +421,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));
>
> Is s->enabled_capabilities initialized somewhere or are we making xbzrle
> disabled by default?
>
>>
>> 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;
>
> Unrelated change.
>
>> s->state = MIG_STATE_SETUP;
>> s->total_time = qemu_get_clock_ms(rt_clock);
>>
>> diff --git a/migration.h b/migration.h
>> index 57572a6..713aae0 100644
>> --- a/migration.h
>> +++ b/migration.h
>> @@ -19,6 +19,7 @@
>> #include "notify.h"
>> #include "error.h"
>> #include "vmstate.h"
>> +#include "qapi-types.h"
>>
>> struct MigrationParams {
>> bool blk;
>> @@ -39,6 +40,7 @@ struct MigrationState
>> void *opaque;
>> MigrationParams params;
>> int64_t total_time;
>> + bool enabled_capabilities[MIGRATION_CAPABILITY_MAX];
>> };
>>
>> void process_incoming_migration(QEMUFile *f);
>> diff --git a/monitor.c b/monitor.c
>> index fd57c5e..e07af97 100644
>> --- a/monitor.c
>> +++ b/monitor.c
>> @@ -2669,6 +2669,13 @@ static mon_cmd_t info_cmds[] = {
>> .mhandler.info = hmp_info_migration_capabilities,
>> },
>> {
>> + .name = "migrate-parameters",
>> + .args_type = "",
>> + .params = "",
>> + .help = "show current migration parameters",
>> + .mhandler.info = hmp_info_migrate_parameters,
>> + },
>> + {
>> .name = "balloon",
>> .args_type = "",
>> .params = "",
>> diff --git a/qapi-schema.json b/qapi-schema.json
>> index b4d4dd6..9d6759d 100644
>> --- a/qapi-schema.json
>> +++ b/qapi-schema.json
>> @@ -345,6 +345,38 @@
>> { 'command': 'query-migration-capabilities', 'returns': ['MigrationCapabilityStatus'] }
>>
>> ##
>> +# @migrate-set-parameters
>> +#
>> +# Enable/Disable the following migration capabilities (like xbzrle)
>> +#
>> +# Since: 1.2
>> +##
>> +{ 'command': 'migrate-set-parameters',
>> + 'data': { 'capabilities': ['MigrationCapabilityStatus'] } }
>> +
>> +##
>> +# @MigrationParameters
>> +#
>> +# @capabilities: @MigrationCapabilityStatus list contain current migration
>> +# capabilities status
>> +# Since: 1.2
>> +##
>> +{ 'type': 'MigrationParameters',
>> + 'data': {'capabilities': ['MigrationCapabilityStatus']} }
>> +
>> +
>> +##
>> +# @query-migrate-parameters
>> +#
>> +# Returns information about the current migration capabilities status
>> +#
>> +# Returns: @MigrationParameters
>> +#
>> +# Since: 1.2
>> +##
>> +{ 'command': 'query-migrate-parameters', 'returns': 'MigrationParameters' }
>> +
>> +##
>> # @MouseInfo:
>> #
>> # Information about a mouse device.
>> diff --git a/qmp-commands.hx b/qmp-commands.hx
>> index c0ed14c..7f40e2a 100644
>> --- a/qmp-commands.hx
>> +++ b/qmp-commands.hx
>> @@ -2081,7 +2081,6 @@ The main json-object contains the following:
>> - "transferred": amount transferred (json-int)
>> - "remaining": amount remaining (json-int)
>> - "total": total (json-int)
>> -
>> Examples:
>>
>> 1. Before the first migration
>> @@ -2092,7 +2091,15 @@ Examples:
>> 2. Migration is done and has succeeded
>>
>> -> { "execute": "query-migrate" }
>> -<- { "return": { "status": "completed" } }
>> +<- { "return": {
>> + "status": "completed",
>> + "ram":{
>> + "transferred":123,
>> + "remaining":123,
>> + "total":246
>> + }
>> + }
>> + }
>>
>> 3. Migration is done and has failed
>>
>> @@ -2165,6 +2172,55 @@ EQMP
>> },
>>
>> SQMP
>> +migrate-set-parameters
>> +-------
>> +
>> +Enable/Disable 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-migrate-parameters
>> +-------
>> +
>> +Query current migration parameters
>> +
>> +- "capabilities": migration capabilities state
>> + - "xbzrle" : XBZRLE state (json-bool)
>> +
>> +Arguments:
>> +
>> +Example:
>> +
>> +-> { "execute": "query-migrate-parameters" }
>> +<- { "return": {
>> + "capabilities" : [ { "capability" : "xbzrle", "state" : false } ]
>> + }
>> + }
>> +EQMP
>> +
>> + {
>> + .name = "query-migrate-parameters",
>> + .args_type = "",
>> + .mhandler.cmd_new = qmp_marshal_input_query_migrate_parameters,
>> + },
>> +
>> +SQMP
>> query-balloon
>> -------------
>>
>
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Qemu-devel] [PATCH 02/11] Add migrate_set_parameter and query-migrate-parameters
2012-07-30 17:41 ` Luiz Capitulino
2012-07-31 7:46 ` Orit Wasserman
@ 2012-07-31 8:03 ` Orit Wasserman
1 sibling, 0 replies; 32+ messages in thread
From: Orit Wasserman @ 2012-07-31 8:03 UTC (permalink / raw)
To: Luiz Capitulino
Cc: peter.maydell, aliguori, quintela, stefanha, qemu-devel, mdroth,
blauwirbel, chegu_vinod, avi, pbonzini, eblake
On 07/30/2012 08:41 PM, Luiz Capitulino wrote:
> On Sun, 29 Jul 2012 12:42:54 +0300
> Orit Wasserman <owasserm@redhat.com> wrote:
>
>> The management can enable/disable a capability for the next migration by using
>> migrate_set_parameter command.
>> The management can query the current migration capabilities using
>> query-migrate-parameters
>
> In general looks good to me, I have a question and a few nitpick comments
> below.
>
>>
>> Signed-off-by: Orit Wasserman <owasserm@redhat.com>
>> Signed-off-by: Juan Quintela <quintela@redhat.com>
>> ---
>> hmp-commands.hx | 16 ++++++++++++
>> hmp.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
>> hmp.h | 2 +
>> migration.c | 42 +++++++++++++++++++++++++++++++-
>> migration.h | 2 +
>> monitor.c | 7 +++++
>> qapi-schema.json | 32 ++++++++++++++++++++++++
>> qmp-commands.hx | 60 ++++++++++++++++++++++++++++++++++++++++++++-
>> 8 files changed, 229 insertions(+), 3 deletions(-)
>>
>> diff --git a/hmp-commands.hx b/hmp-commands.hx
>> index 8786148..3e15338 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 = "capability state",
>> + .help = "Enable/Disable 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 user network stack connection states
>> show migration status
>> @item info migration_capabilities
>> show migration capabilities
>> +@item info migrate_parameters
>> +show current migration parameters
>> @item info balloon
>> show balloon information
>> @item info qtree
>> diff --git a/hmp.c b/hmp.c
>> index 5c7d0be..f2f63fd 100644
>> --- a/hmp.c
>> +++ b/hmp.c
>> @@ -131,8 +131,22 @@ void hmp_info_mice(Monitor *mon)
>> void hmp_info_migrate(Monitor *mon)
>> {
>> MigrationInfo *info;
>> + MigrationCapabilityStatusList *cap;
>> + MigrationParameters *params;
>>
>> info = qmp_query_migrate(NULL);
>> + params = qmp_query_migrate_parameters(NULL);
>> +
>> + /* do not display parameters during setup */
>> + if (info->has_status && params->capabilities) {
>> + monitor_printf(mon, "capabilities: ");
>> + for (cap = params->capabilities; 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 +173,7 @@ void hmp_info_migrate(Monitor *mon)
>> }
>>
>> qapi_free_MigrationInfo(info);
>> + qapi_free_MigrationParameters(params);
>> }
>>
>> void hmp_info_migration_capabilities(Monitor *mon)
>> @@ -180,6 +195,27 @@ void hmp_info_migration_capabilities(Monitor *mon)
>> qapi_free_MigrationCapabilityStatusList(caps_list);
>> }
>>
>> +void hmp_info_migrate_parameters(Monitor *mon)
>> +{
>> +
>> + MigrationCapabilityStatusList *cap;
>> + MigrationParameters *params;
>> +
>> + params = qmp_query_migrate_parameters(NULL);
>> +
>> + if (params->capabilities) {
>> + monitor_printf(mon, "capabilities: ");
>> + for (cap = params->capabilities; cap; cap = cap->next) {
>> + monitor_printf(mon, "%s: %s ",
>> + MigrationCapability_lookup[cap->value->capability],
>> + cap->value->state ? "on" : "off");
>> + }
>> + monitor_printf(mon, "\n");
>> + }
>> +
>> + qapi_free_MigrationParameters(params);
>> +}
>> +
>> void hmp_info_cpus(Monitor *mon)
>> {
>> CpuInfoList *cpu_list, *cpu;
>> @@ -754,6 +790,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;
>> + MigrationCapabilityStatusList *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));
>> + }
>
> This if shouldn't be necessary, right?
>
>> + params->value = g_malloc0(sizeof(*params->value));
>> + params->value->capability = i;
>> + params->value->state = state;
>> + params->next = NULL;
>
> nitpick: I'd make the code ready for future capabilities.
>
>> + qmp_migrate_set_parameters(params, &err);
>> + break;
>> + }
>> + }
>> +
>> + if (i == MIGRATION_CAPABILITY_MAX) {
>> + error_set(&err, QERR_INVALID_PARAMETER, cap);
>> + }
>> +
>> + qapi_free_MigrationCapabilityStatusList(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 2fb44ca..ceb2f06 100644
>> --- a/hmp.h
>> +++ b/hmp.h
>> @@ -26,6 +26,7 @@ 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_migrate_parameters(Monitor *mon);
>> void hmp_info_cpus(Monitor *mon);
>> void hmp_info_block(Monitor *mon);
>> void hmp_info_blockstats(Monitor *mon);
>> @@ -52,6 +53,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 8c27347..e844290 100644
>> --- a/migration.c
>> +++ b/migration.c
>> @@ -113,6 +113,25 @@ uint64_t migrate_max_downtime(void)
>> return max_downtime;
>> }
>>
>> +MigrationParameters *qmp_query_migrate_parameters(Error **errp)
>> +{
>> + MigrationParameters *params = g_malloc0(sizeof(*params));
>> + MigrationState *s = migrate_get_current();
>> + int i;
>> +
>> + params->capabilities = g_malloc0(sizeof(*params->capabilities));
>> +
>> + for (i = 0; i < MIGRATION_CAPABILITY_MAX; i++) {
>> + params->capabilities->value =
>> + g_malloc(sizeof(*params->capabilities->value));
>> + params->capabilities->value->capability = i;
>> + params->capabilities->value->state = s->enabled_capabilities[i];
>> + params->capabilities->next = NULL;
>> + }
>> +
>> + return params;
>> +}
>> +
>> MigrationInfo *qmp_query_migrate(Error **errp)
>> {
>> MigrationInfo *info = g_malloc0(sizeof(*info));
>> @@ -177,6 +196,22 @@ MigrationCapabilityStatusList *qmp_query_migration_capabilities(Error **errp)
>> return caps_list;
>> }
>>
>> +void qmp_migrate_set_parameters(MigrationCapabilityStatusList *params,
>> + Error **errp)
>> +{
>> + MigrationState *s = migrate_get_current();
>> + MigrationCapabilityStatusList *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)
>> @@ -386,12 +421,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));
>
> Is s->enabled_capabilities initialized somewhere or are we making xbzrle
> disabled by default?
It is automatically zeroed because it is static, which means all capabilities are
disabled by default
Orit
>
>>
>> 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;
>
> Unrelated change.
>
>> s->state = MIG_STATE_SETUP;
>> s->total_time = qemu_get_clock_ms(rt_clock);
>>
>> diff --git a/migration.h b/migration.h
>> index 57572a6..713aae0 100644
>> --- a/migration.h
>> +++ b/migration.h
>> @@ -19,6 +19,7 @@
>> #include "notify.h"
>> #include "error.h"
>> #include "vmstate.h"
>> +#include "qapi-types.h"
>>
>> struct MigrationParams {
>> bool blk;
>> @@ -39,6 +40,7 @@ struct MigrationState
>> void *opaque;
>> MigrationParams params;
>> int64_t total_time;
>> + bool enabled_capabilities[MIGRATION_CAPABILITY_MAX];
>> };
>>
>> void process_incoming_migration(QEMUFile *f);
>> diff --git a/monitor.c b/monitor.c
>> index fd57c5e..e07af97 100644
>> --- a/monitor.c
>> +++ b/monitor.c
>> @@ -2669,6 +2669,13 @@ static mon_cmd_t info_cmds[] = {
>> .mhandler.info = hmp_info_migration_capabilities,
>> },
>> {
>> + .name = "migrate-parameters",
>> + .args_type = "",
>> + .params = "",
>> + .help = "show current migration parameters",
>> + .mhandler.info = hmp_info_migrate_parameters,
>> + },
>> + {
>> .name = "balloon",
>> .args_type = "",
>> .params = "",
>> diff --git a/qapi-schema.json b/qapi-schema.json
>> index b4d4dd6..9d6759d 100644
>> --- a/qapi-schema.json
>> +++ b/qapi-schema.json
>> @@ -345,6 +345,38 @@
>> { 'command': 'query-migration-capabilities', 'returns': ['MigrationCapabilityStatus'] }
>>
>> ##
>> +# @migrate-set-parameters
>> +#
>> +# Enable/Disable the following migration capabilities (like xbzrle)
>> +#
>> +# Since: 1.2
>> +##
>> +{ 'command': 'migrate-set-parameters',
>> + 'data': { 'capabilities': ['MigrationCapabilityStatus'] } }
>> +
>> +##
>> +# @MigrationParameters
>> +#
>> +# @capabilities: @MigrationCapabilityStatus list contain current migration
>> +# capabilities status
>> +# Since: 1.2
>> +##
>> +{ 'type': 'MigrationParameters',
>> + 'data': {'capabilities': ['MigrationCapabilityStatus']} }
>> +
>> +
>> +##
>> +# @query-migrate-parameters
>> +#
>> +# Returns information about the current migration capabilities status
>> +#
>> +# Returns: @MigrationParameters
>> +#
>> +# Since: 1.2
>> +##
>> +{ 'command': 'query-migrate-parameters', 'returns': 'MigrationParameters' }
>> +
>> +##
>> # @MouseInfo:
>> #
>> # Information about a mouse device.
>> diff --git a/qmp-commands.hx b/qmp-commands.hx
>> index c0ed14c..7f40e2a 100644
>> --- a/qmp-commands.hx
>> +++ b/qmp-commands.hx
>> @@ -2081,7 +2081,6 @@ The main json-object contains the following:
>> - "transferred": amount transferred (json-int)
>> - "remaining": amount remaining (json-int)
>> - "total": total (json-int)
>> -
>> Examples:
>>
>> 1. Before the first migration
>> @@ -2092,7 +2091,15 @@ Examples:
>> 2. Migration is done and has succeeded
>>
>> -> { "execute": "query-migrate" }
>> -<- { "return": { "status": "completed" } }
>> +<- { "return": {
>> + "status": "completed",
>> + "ram":{
>> + "transferred":123,
>> + "remaining":123,
>> + "total":246
>> + }
>> + }
>> + }
>>
>> 3. Migration is done and has failed
>>
>> @@ -2165,6 +2172,55 @@ EQMP
>> },
>>
>> SQMP
>> +migrate-set-parameters
>> +-------
>> +
>> +Enable/Disable 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-migrate-parameters
>> +-------
>> +
>> +Query current migration parameters
>> +
>> +- "capabilities": migration capabilities state
>> + - "xbzrle" : XBZRLE state (json-bool)
>> +
>> +Arguments:
>> +
>> +Example:
>> +
>> +-> { "execute": "query-migrate-parameters" }
>> +<- { "return": {
>> + "capabilities" : [ { "capability" : "xbzrle", "state" : false } ]
>> + }
>> + }
>> +EQMP
>> +
>> + {
>> + .name = "query-migrate-parameters",
>> + .args_type = "",
>> + .mhandler.cmd_new = qmp_marshal_input_query_migrate_parameters,
>> + },
>> +
>> +SQMP
>> query-balloon
>> -------------
>>
>
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [Qemu-devel] [PATCH 02/11] Add migrate_set_parameter and query-migrate-parameters
2012-07-31 7:46 ` Orit Wasserman
@ 2012-07-31 13:09 ` Luiz Capitulino
0 siblings, 0 replies; 32+ messages in thread
From: Luiz Capitulino @ 2012-07-31 13:09 UTC (permalink / raw)
To: Orit Wasserman
Cc: peter.maydell, aliguori, quintela, stefanha, qemu-devel, mdroth,
blauwirbel, chegu_vinod, avi, pbonzini, eblake
On Tue, 31 Jul 2012 10:46:02 +0300
Orit Wasserman <owasserm@redhat.com> wrote:
> On 07/30/2012 08:41 PM, Luiz Capitulino wrote:
> > On Sun, 29 Jul 2012 12:42:54 +0300
> > Orit Wasserman <owasserm@redhat.com> wrote:
> >
> >> The management can enable/disable a capability for the next migration by using
> >> migrate_set_parameter command.
> >> The management can query the current migration capabilities using
> >> query-migrate-parameters
> >
> > In general looks good to me, I have a question and a few nitpick comments
> > below.
> >
> >>
> >> Signed-off-by: Orit Wasserman <owasserm@redhat.com>
> >> Signed-off-by: Juan Quintela <quintela@redhat.com>
> >> ---
> >> hmp-commands.hx | 16 ++++++++++++
> >> hmp.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
> >> hmp.h | 2 +
> >> migration.c | 42 +++++++++++++++++++++++++++++++-
> >> migration.h | 2 +
> >> monitor.c | 7 +++++
> >> qapi-schema.json | 32 ++++++++++++++++++++++++
> >> qmp-commands.hx | 60 ++++++++++++++++++++++++++++++++++++++++++++-
> >> 8 files changed, 229 insertions(+), 3 deletions(-)
> >>
> >> diff --git a/hmp-commands.hx b/hmp-commands.hx
> >> index 8786148..3e15338 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 = "capability state",
> >> + .help = "Enable/Disable 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 user network stack connection states
> >> show migration status
> >> @item info migration_capabilities
> >> show migration capabilities
> >> +@item info migrate_parameters
> >> +show current migration parameters
> >> @item info balloon
> >> show balloon information
> >> @item info qtree
> >> diff --git a/hmp.c b/hmp.c
> >> index 5c7d0be..f2f63fd 100644
> >> --- a/hmp.c
> >> +++ b/hmp.c
> >> @@ -131,8 +131,22 @@ void hmp_info_mice(Monitor *mon)
> >> void hmp_info_migrate(Monitor *mon)
> >> {
> >> MigrationInfo *info;
> >> + MigrationCapabilityStatusList *cap;
> >> + MigrationParameters *params;
> >>
> >> info = qmp_query_migrate(NULL);
> >> + params = qmp_query_migrate_parameters(NULL);
> >> +
> >> + /* do not display parameters during setup */
> >> + if (info->has_status && params->capabilities) {
> >> + monitor_printf(mon, "capabilities: ");
> >> + for (cap = params->capabilities; 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 +173,7 @@ void hmp_info_migrate(Monitor *mon)
> >> }
> >>
> >> qapi_free_MigrationInfo(info);
> >> + qapi_free_MigrationParameters(params);
> >> }
> >>
> >> void hmp_info_migration_capabilities(Monitor *mon)
> >> @@ -180,6 +195,27 @@ void hmp_info_migration_capabilities(Monitor *mon)
> >> qapi_free_MigrationCapabilityStatusList(caps_list);
> >> }
> >>
> >> +void hmp_info_migrate_parameters(Monitor *mon)
> >> +{
> >> +
> >> + MigrationCapabilityStatusList *cap;
> >> + MigrationParameters *params;
> >> +
> >> + params = qmp_query_migrate_parameters(NULL);
> >> +
> >> + if (params->capabilities) {
> >> + monitor_printf(mon, "capabilities: ");
> >> + for (cap = params->capabilities; cap; cap = cap->next) {
> >> + monitor_printf(mon, "%s: %s ",
> >> + MigrationCapability_lookup[cap->value->capability],
> >> + cap->value->state ? "on" : "off");
> >> + }
> >> + monitor_printf(mon, "\n");
> >> + }
> >> +
> >> + qapi_free_MigrationParameters(params);
> >> +}
> >> +
> >> void hmp_info_cpus(Monitor *mon)
> >> {
> >> CpuInfoList *cpu_list, *cpu;
> >> @@ -754,6 +790,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;
> >> + MigrationCapabilityStatusList *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));
> >> + }
> >
> > This if shouldn't be necessary, right?
> You are right I can always allocate it.
> >
> >> + params->value = g_malloc0(sizeof(*params->value));
> >> + params->value->capability = i;
> >> + params->value->state = state;
> >> + params->next = NULL;
> >
> > nitpick: I'd make the code ready for future capabilities.
> Could you give me a bit more details ?
This is not a proper list, it will break when we add a new capability.
But that comment doesn't apply here, I meant to add that command to
qmp_query_migrate_parameters()'s hunk.
>
> Orit
> >
> >> + qmp_migrate_set_parameters(params, &err);
> >> + break;
> >> + }
> >> + }
> >> +
> >> + if (i == MIGRATION_CAPABILITY_MAX) {
> >> + error_set(&err, QERR_INVALID_PARAMETER, cap);
> >> + }
> >> +
> >> + qapi_free_MigrationCapabilityStatusList(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 2fb44ca..ceb2f06 100644
> >> --- a/hmp.h
> >> +++ b/hmp.h
> >> @@ -26,6 +26,7 @@ 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_migrate_parameters(Monitor *mon);
> >> void hmp_info_cpus(Monitor *mon);
> >> void hmp_info_block(Monitor *mon);
> >> void hmp_info_blockstats(Monitor *mon);
> >> @@ -52,6 +53,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 8c27347..e844290 100644
> >> --- a/migration.c
> >> +++ b/migration.c
> >> @@ -113,6 +113,25 @@ uint64_t migrate_max_downtime(void)
> >> return max_downtime;
> >> }
> >>
> >> +MigrationParameters *qmp_query_migrate_parameters(Error **errp)
> >> +{
> >> + MigrationParameters *params = g_malloc0(sizeof(*params));
> >> + MigrationState *s = migrate_get_current();
> >> + int i;
> >> +
> >> + params->capabilities = g_malloc0(sizeof(*params->capabilities));
> >> +
> >> + for (i = 0; i < MIGRATION_CAPABILITY_MAX; i++) {
> >> + params->capabilities->value =
> >> + g_malloc(sizeof(*params->capabilities->value));
> >> + params->capabilities->value->capability = i;
> >> + params->capabilities->value->state = s->enabled_capabilities[i];
> >> + params->capabilities->next = NULL;
> >> + }
> >> +
> >> + return params;
> >> +}
> >> +
> >> MigrationInfo *qmp_query_migrate(Error **errp)
> >> {
> >> MigrationInfo *info = g_malloc0(sizeof(*info));
> >> @@ -177,6 +196,22 @@ MigrationCapabilityStatusList *qmp_query_migration_capabilities(Error **errp)
> >> return caps_list;
> >> }
> >>
> >> +void qmp_migrate_set_parameters(MigrationCapabilityStatusList *params,
> >> + Error **errp)
> >> +{
> >> + MigrationState *s = migrate_get_current();
> >> + MigrationCapabilityStatusList *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)
> >> @@ -386,12 +421,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));
> >
> > Is s->enabled_capabilities initialized somewhere or are we making xbzrle
> > disabled by default?
> >
> >>
> >> 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;
> >
> > Unrelated change.
> >
> >> s->state = MIG_STATE_SETUP;
> >> s->total_time = qemu_get_clock_ms(rt_clock);
> >>
> >> diff --git a/migration.h b/migration.h
> >> index 57572a6..713aae0 100644
> >> --- a/migration.h
> >> +++ b/migration.h
> >> @@ -19,6 +19,7 @@
> >> #include "notify.h"
> >> #include "error.h"
> >> #include "vmstate.h"
> >> +#include "qapi-types.h"
> >>
> >> struct MigrationParams {
> >> bool blk;
> >> @@ -39,6 +40,7 @@ struct MigrationState
> >> void *opaque;
> >> MigrationParams params;
> >> int64_t total_time;
> >> + bool enabled_capabilities[MIGRATION_CAPABILITY_MAX];
> >> };
> >>
> >> void process_incoming_migration(QEMUFile *f);
> >> diff --git a/monitor.c b/monitor.c
> >> index fd57c5e..e07af97 100644
> >> --- a/monitor.c
> >> +++ b/monitor.c
> >> @@ -2669,6 +2669,13 @@ static mon_cmd_t info_cmds[] = {
> >> .mhandler.info = hmp_info_migration_capabilities,
> >> },
> >> {
> >> + .name = "migrate-parameters",
> >> + .args_type = "",
> >> + .params = "",
> >> + .help = "show current migration parameters",
> >> + .mhandler.info = hmp_info_migrate_parameters,
> >> + },
> >> + {
> >> .name = "balloon",
> >> .args_type = "",
> >> .params = "",
> >> diff --git a/qapi-schema.json b/qapi-schema.json
> >> index b4d4dd6..9d6759d 100644
> >> --- a/qapi-schema.json
> >> +++ b/qapi-schema.json
> >> @@ -345,6 +345,38 @@
> >> { 'command': 'query-migration-capabilities', 'returns': ['MigrationCapabilityStatus'] }
> >>
> >> ##
> >> +# @migrate-set-parameters
> >> +#
> >> +# Enable/Disable the following migration capabilities (like xbzrle)
> >> +#
> >> +# Since: 1.2
> >> +##
> >> +{ 'command': 'migrate-set-parameters',
> >> + 'data': { 'capabilities': ['MigrationCapabilityStatus'] } }
> >> +
> >> +##
> >> +# @MigrationParameters
> >> +#
> >> +# @capabilities: @MigrationCapabilityStatus list contain current migration
> >> +# capabilities status
> >> +# Since: 1.2
> >> +##
> >> +{ 'type': 'MigrationParameters',
> >> + 'data': {'capabilities': ['MigrationCapabilityStatus']} }
> >> +
> >> +
> >> +##
> >> +# @query-migrate-parameters
> >> +#
> >> +# Returns information about the current migration capabilities status
> >> +#
> >> +# Returns: @MigrationParameters
> >> +#
> >> +# Since: 1.2
> >> +##
> >> +{ 'command': 'query-migrate-parameters', 'returns': 'MigrationParameters' }
> >> +
> >> +##
> >> # @MouseInfo:
> >> #
> >> # Information about a mouse device.
> >> diff --git a/qmp-commands.hx b/qmp-commands.hx
> >> index c0ed14c..7f40e2a 100644
> >> --- a/qmp-commands.hx
> >> +++ b/qmp-commands.hx
> >> @@ -2081,7 +2081,6 @@ The main json-object contains the following:
> >> - "transferred": amount transferred (json-int)
> >> - "remaining": amount remaining (json-int)
> >> - "total": total (json-int)
> >> -
> >> Examples:
> >>
> >> 1. Before the first migration
> >> @@ -2092,7 +2091,15 @@ Examples:
> >> 2. Migration is done and has succeeded
> >>
> >> -> { "execute": "query-migrate" }
> >> -<- { "return": { "status": "completed" } }
> >> +<- { "return": {
> >> + "status": "completed",
> >> + "ram":{
> >> + "transferred":123,
> >> + "remaining":123,
> >> + "total":246
> >> + }
> >> + }
> >> + }
> >>
> >> 3. Migration is done and has failed
> >>
> >> @@ -2165,6 +2172,55 @@ EQMP
> >> },
> >>
> >> SQMP
> >> +migrate-set-parameters
> >> +-------
> >> +
> >> +Enable/Disable 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-migrate-parameters
> >> +-------
> >> +
> >> +Query current migration parameters
> >> +
> >> +- "capabilities": migration capabilities state
> >> + - "xbzrle" : XBZRLE state (json-bool)
> >> +
> >> +Arguments:
> >> +
> >> +Example:
> >> +
> >> +-> { "execute": "query-migrate-parameters" }
> >> +<- { "return": {
> >> + "capabilities" : [ { "capability" : "xbzrle", "state" : false } ]
> >> + }
> >> + }
> >> +EQMP
> >> +
> >> + {
> >> + .name = "query-migrate-parameters",
> >> + .args_type = "",
> >> + .mhandler.cmd_new = qmp_marshal_input_query_migrate_parameters,
> >> + },
> >> +
> >> +SQMP
> >> query-balloon
> >> -------------
> >>
> >
>
^ permalink raw reply [flat|nested] 32+ messages in thread
* [Qemu-devel] [PATCH 00/11] Migration next v8
@ 2012-07-31 18:54 Orit Wasserman
2012-07-31 18:54 ` [Qemu-devel] [PATCH 01/11] Add migration capabilities Orit Wasserman
` (10 more replies)
0 siblings, 11 replies; 32+ messages in thread
From: Orit Wasserman @ 2012-07-31 18:54 UTC (permalink / raw)
To: qemu-devel
Cc: peter.maydell, aliguori, quintela, stefanha, mdroth, lcapitulino,
blauwirbel, Orit Wasserman, chegu_vinod, avi, pbonzini, eblake
Changes from v7:
rename migrate-set-parameter to migrate-set-capabilities
rename query-migrate-parameters to query-migrate-capabilities
renamse query-migration-capabilities to query-migration-supported-capabilities
fix query_migration_supported_capabilties to return a list
add query-migrate-cache-size commands
fix other review comment by Luiz and Eric
Changes from v6:
fix memory leak in cache_init.
using size_t for cache_get_cache_pos.
fix qapi-schema.json comments.
fix other comments by Eric Blake.
changes from v5:
Add query-migrate-parameters that display the migration parameters
(currently only capabilities I will add the other parameters separately).
Remove capabilities from query-migrate.
Please review
Juan Quintela (1):
Restart optimization on stage3 update version
Orit Wasserman (10):
Add migration capabilities
Add migrate_set_parameter and query-migrate-parameters
Add XBZRLE documentation
Add cache handling functions
Add uleb encoding/decoding functions
Add xbzrle_encode_buffer and xbzrle_decode_buffer functions
Add XBZRLE to ram_save_block and ram_save_live
Add migrate_set_cachesize command
Add migration accounting for normal and duplicate pages
Add XBZRLE statistics
Makefile.objs | 1 +
arch_init.c | 246 ++++++++++++++++++++++++++++++++++++++++++++-
cutils.c | 42 ++++++++
docs/xbzrle.txt | 136 +++++++++++++++++++++++++
hmp-commands.hx | 40 ++++++++
hmp.c | 124 +++++++++++++++++++++++
hmp.h | 5 +
include/qemu/page_cache.h | 79 +++++++++++++++
migration.c | 119 ++++++++++++++++++++++
migration.h | 21 ++++
monitor.c | 21 ++++
page_cache.c | 218 +++++++++++++++++++++++++++++++++++++++
qapi-schema.json | 137 ++++++++++++++++++++++++-
qemu-common.h | 21 ++++
qmp-commands.hx | 180 ++++++++++++++++++++++++++++++++-
savevm.c | 159 +++++++++++++++++++++++++++++
16 files changed, 1537 insertions(+), 12 deletions(-)
create mode 100644 docs/xbzrle.txt
create mode 100644 include/qemu/page_cache.h
create mode 100644 page_cache.c
--
1.7.7.6
^ permalink raw reply [flat|nested] 32+ messages in thread
* [Qemu-devel] [PATCH 01/11] Add migration capabilities
2012-07-31 18:54 [Qemu-devel] [PATCH 00/11] Migration next v8 Orit Wasserman
@ 2012-07-31 18:54 ` Orit Wasserman
2012-07-31 18:54 ` [Qemu-devel] [PATCH 02/11] Add migrate_set_parameter and query-migrate-parameters Orit Wasserman
` (9 subsequent siblings)
10 siblings, 0 replies; 32+ messages in thread
From: Orit Wasserman @ 2012-07-31 18:54 UTC (permalink / raw)
To: qemu-devel
Cc: peter.maydell, aliguori, quintela, stefanha, mdroth, lcapitulino,
blauwirbel, Orit Wasserman, chegu_vinod, avi, pbonzini, eblake
Add migration capabilities that can be queried by the management using
query-migration-supported-capabilities command.
The management can query the source QEMU and the destination QEMU in order to
verify both support some migration capability (currently only XBZRLE).
Signed-off-by: Orit Wasserman <owasserm@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
---
hmp-commands.hx | 2 ++
hmp.c | 21 +++++++++++++++++++++
hmp.h | 1 +
migration.c | 12 ++++++++++++
monitor.c | 7 +++++++
qapi-schema.json | 39 +++++++++++++++++++++++++++++++++++++++
qmp-commands.hx | 25 +++++++++++++++++++++++++
7 files changed, 107 insertions(+), 0 deletions(-)
diff --git a/hmp-commands.hx b/hmp-commands.hx
index eea8b32..8267237 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1417,6 +1417,8 @@ show CPU statistics
show user network stack connection states
@item info migrate
show migration status
+@item info migration_supported_capabilities
+show migration supported capabilities
@item info balloon
show balloon information
@item info qtree
diff --git a/hmp.c b/hmp.c
index 6b72a64..2ff71a3 100644
--- a/hmp.c
+++ b/hmp.c
@@ -161,6 +161,27 @@ void hmp_info_migrate(Monitor *mon)
qapi_free_MigrationInfo(info);
}
+void hmp_info_migration_supported_capabilities(Monitor *mon)
+{
+ MigrationCapabilityStatusList *caps_list, *cap;
+
+ caps_list = qmp_query_migration_supported_capabilities(NULL);
+ if (!caps_list) {
+ monitor_printf(mon, "No supported migration capabilities found\n");
+ return;
+ }
+
+ for (cap = caps_list; cap; cap = cap->next) {
+ monitor_printf(mon, "%s: %s ",
+ MigrationCapability_lookup[cap->value->capability],
+ cap->value->state ? "on" : "off");
+ }
+
+ monitor_printf(mon, "\n");
+
+ qapi_free_MigrationCapabilityStatusList(caps_list);
+}
+
void hmp_info_cpus(Monitor *mon)
{
CpuInfoList *cpu_list, *cpu;
diff --git a/hmp.h b/hmp.h
index 8d2b0d7..8442c22 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_supported_capabilities(Monitor *mon);
void hmp_info_cpus(Monitor *mon);
void hmp_info_block(Monitor *mon);
void hmp_info_blockstats(Monitor *mon);
diff --git a/migration.c b/migration.c
index 8db1b43..35444f7 100644
--- a/migration.c
+++ b/migration.c
@@ -166,6 +166,18 @@ MigrationInfo *qmp_query_migrate(Error **errp)
return info;
}
+MigrationCapabilityStatusList *
+qmp_query_migration_supported_capabilities(Error **errp)
+{
+ MigrationCapabilityStatusList *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;
+}
+
/* shared migration helpers */
static int migrate_fd_cleanup(MigrationState *s)
diff --git a/monitor.c b/monitor.c
index 09aa3cd..43f7df5 100644
--- a/monitor.c
+++ b/monitor.c
@@ -2662,6 +2662,13 @@ static mon_cmd_t info_cmds[] = {
.mhandler.info = hmp_info_migrate,
},
{
+ .name = "migration_supported_capabilities",
+ .args_type = "",
+ .params = "",
+ .help = "show migration supported capabilities",
+ .mhandler.info = hmp_info_migration_supported_capabilities,
+ },
+ {
.name = "balloon",
.args_type = "",
.params = "",
diff --git a/qapi-schema.json b/qapi-schema.json
index a92adb1..68d0fbb 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -306,6 +306,45 @@
{ 'command': 'query-migrate', 'returns': 'MigrationInfo' }
##
+# @MigrationCapability
+#
+# Migration capabilities enumeration
+#
+# @xbzrle: Migration supports xbzrle (Xor Based Zero Run Length Encoding).
+# This feature allows us to minimize migration traffic for certain work
+# loads, by sending compressed difference of the pages
+#
+# Since: 1.2
+##
+{ 'enum': 'MigrationCapability',
+ 'data': ['xbzrle'] }
+
+##
+# @MigrationCapabilityStatus
+#
+# Migration capability information
+#
+# @capability: capability enum
+#
+# @state: capability state bool
+#
+# Since: 1.2
+##
+{ 'type': 'MigrationCapabilityStatus',
+ 'data': { 'capability' : 'MigrationCapability', 'state' : 'bool' } }
+
+##
+# @query-migration-supported-capabilities
+#
+# Returns information about current migration process capabilities.
+#
+# Returns: @MigrationCapabilityStatus list
+#
+# Since: 1.2
+##
+{ 'command': 'query-migration-supported-capabilities', 'returns': ['MigrationCapabilityStatus'] }
+
+##
# @MouseInfo:
#
# Information about a mouse device.
diff --git a/qmp-commands.hx b/qmp-commands.hx
index e3cf3c5..16fbcef 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -2141,6 +2141,31 @@ EQMP
},
SQMP
+query-migration-supported-capabilities
+-------
+
+Query migration supported capabilities
+
+- "xbzrle": xbzrle support
+
+Arguments:
+
+Example:
+
+-> { "execute": "query-migration-supported-capabilities"}
+<- { "return": [ { "capability": "xbzrle", "state": true },
+ { "capability": "foobar", "state": false } ] }
+
+EQMP
+
+ {
+ .name = "query-migration-supported-capabilities",
+ .args_type = "",
+ .mhandler.cmd_new =
+ qmp_marshal_input_query_migration_supported_capabilities,
+ },
+
+SQMP
query-balloon
-------------
--
1.7.7.6
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [Qemu-devel] [PATCH 02/11] Add migrate_set_parameter and query-migrate-parameters
2012-07-31 18:54 [Qemu-devel] [PATCH 00/11] Migration next v8 Orit Wasserman
2012-07-31 18:54 ` [Qemu-devel] [PATCH 01/11] Add migration capabilities Orit Wasserman
@ 2012-07-31 18:54 ` Orit Wasserman
2012-07-31 19:29 ` Eric Blake
2012-07-31 20:05 ` [Qemu-devel] [PATCH 02/11] Add migrate_set_capabilities and query-migrate-capabilities Orit Wasserman
2012-07-31 18:54 ` [Qemu-devel] [PATCH 03/11] Add XBZRLE documentation Orit Wasserman
` (8 subsequent siblings)
10 siblings, 2 replies; 32+ messages in thread
From: Orit Wasserman @ 2012-07-31 18:54 UTC (permalink / raw)
To: qemu-devel
Cc: peter.maydell, aliguori, quintela, stefanha, mdroth, lcapitulino,
blauwirbel, Orit Wasserman, chegu_vinod, avi, pbonzini, eblake
The management can enable/disable a capability for the next migration by using
migrate_set_capabilities QMP command.
The management can query the current migration capabilities using
query-migrate-capabilities QMP command.
The user can use migrate_set_capability and 'info migrate_capabilities' HMP
commands.
Signed-off-by: Orit Wasserman <owasserm@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
---
hmp-commands.hx | 16 +++++++++++++
hmp.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
hmp.h | 2 +
migration.c | 41 ++++++++++++++++++++++++++++++++++
migration.h | 2 +
monitor.c | 7 +++++
qapi-schema.json | 32 ++++++++++++++++++++++++++
qmp-commands.hx | 60 ++++++++++++++++++++++++++++++++++++++++++++++++-
8 files changed, 223 insertions(+), 2 deletions(-)
diff --git a/hmp-commands.hx b/hmp-commands.hx
index 8267237..f4c8495 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_capability",
+ .args_type = "capability:s,state:b",
+ .params = "capability state",
+ .help = "Enable/Disable the usage of a capability for migration",
+ .mhandler.cmd = hmp_migrate_set_capability,
+ },
+
+STEXI
+@item migrate_set_capability @var{capability} @var{state}
+@findex migrate_set_capability
+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 user network stack connection states
show migration status
@item info migration_supported_capabilities
show migration supported capabilities
+@item info migrate_capabilities
+show current migration capabilities
@item info balloon
show balloon information
@item info qtree
diff --git a/hmp.c b/hmp.c
index 2ff71a3..463b730 100644
--- a/hmp.c
+++ b/hmp.c
@@ -131,8 +131,21 @@ void hmp_info_mice(Monitor *mon)
void hmp_info_migrate(Monitor *mon)
{
MigrationInfo *info;
+ MigrationCapabilityStatusList *caps, *cap;
info = qmp_query_migrate(NULL);
+ caps = qmp_query_migrate_capabilities(NULL);
+
+ /* do not display parameters during setup */
+ if (info->has_status && caps) {
+ monitor_printf(mon, "capabilities: ");
+ for (cap = caps; 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 +172,7 @@ void hmp_info_migrate(Monitor *mon)
}
qapi_free_MigrationInfo(info);
+ qapi_free_MigrationCapabilityStatusList(caps);
}
void hmp_info_migration_supported_capabilities(Monitor *mon)
@@ -182,6 +196,25 @@ void hmp_info_migration_supported_capabilities(Monitor *mon)
qapi_free_MigrationCapabilityStatusList(caps_list);
}
+void hmp_info_migrate_capabilities(Monitor *mon)
+{
+ MigrationCapabilityStatusList *caps, *cap;
+
+ caps = qmp_query_migrate_capabilities(NULL);
+
+ if (caps) {
+ monitor_printf(mon, "capabilities: ");
+ for (cap = caps; cap; cap = cap->next) {
+ monitor_printf(mon, "%s: %s ",
+ MigrationCapability_lookup[cap->value->capability],
+ cap->value->state ? "on" : "off");
+ }
+ monitor_printf(mon, "\n");
+ }
+
+ qapi_free_MigrationCapabilityStatusList(caps);
+}
+
void hmp_info_cpus(Monitor *mon)
{
CpuInfoList *cpu_list, *cpu;
@@ -756,6 +789,38 @@ void hmp_migrate_set_speed(Monitor *mon, const QDict *qdict)
qmp_migrate_set_speed(value, NULL);
}
+void hmp_migrate_set_capability(Monitor *mon, const QDict *qdict)
+{
+ const char *cap = qdict_get_str(qdict, "capability");
+ bool state = qdict_get_bool(qdict, "state");
+ Error *err = NULL;
+ MigrationCapabilityStatusList *caps = g_malloc0(sizeof(*caps));
+ int i;
+
+ for (i = 0; i < MIGRATION_CAPABILITY_MAX; i++) {
+ if (strcmp(cap, MigrationCapability_lookup[i]) == 0) {
+ caps->value = g_malloc0(sizeof(*caps->value));
+ caps->value->capability = i;
+ caps->value->state = state;
+ caps->next = NULL;
+ qmp_migrate_set_capabilities(caps, &err);
+ break;
+ }
+ }
+
+ if (i == MIGRATION_CAPABILITY_MAX) {
+ error_set(&err, QERR_INVALID_PARAMETER, cap);
+ }
+
+ qapi_free_MigrationCapabilityStatusList(caps);
+
+ 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 8442c22..f2a890f 100644
--- a/hmp.h
+++ b/hmp.h
@@ -26,6 +26,7 @@ void hmp_info_chardev(Monitor *mon);
void hmp_info_mice(Monitor *mon);
void hmp_info_migrate(Monitor *mon);
void hmp_info_migration_supported_capabilities(Monitor *mon);
+void hmp_info_migrate_capabilities(Monitor *mon);
void hmp_info_cpus(Monitor *mon);
void hmp_info_block(Monitor *mon);
void hmp_info_blockstats(Monitor *mon);
@@ -52,6 +53,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_capability(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 35444f7..4b52f36 100644
--- a/migration.c
+++ b/migration.c
@@ -113,6 +113,25 @@ uint64_t migrate_max_downtime(void)
return max_downtime;
}
+MigrationCapabilityStatusList *qmp_query_migrate_capabilities(Error **errp)
+{
+ MigrationCapabilityStatusList *caps = g_malloc0(sizeof(*caps));
+ MigrationCapabilityStatusList *next = NULL;
+ MigrationState *s = migrate_get_current();
+ int i;
+
+ for (i = 0; i < MIGRATION_CAPABILITY_MAX; i++) {
+ caps->value =
+ g_malloc(sizeof(*caps->value));
+ caps->value->capability = i;
+ caps->value->state = s->enabled_capabilities[i];
+ caps->next = next;
+ next = caps;
+ }
+
+ return caps;
+}
+
MigrationInfo *qmp_query_migrate(Error **errp)
{
MigrationInfo *info = g_malloc0(sizeof(*info));
@@ -178,6 +197,22 @@ qmp_query_migration_supported_capabilities(Error **errp)
return caps_list;
}
+void qmp_migrate_set_capabilities(MigrationCapabilityStatusList *params,
+ Error **errp)
+{
+ MigrationState *s = migrate_get_current();
+ MigrationCapabilityStatusList *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)
@@ -387,10 +422,16 @@ 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;
diff --git a/migration.h b/migration.h
index 57572a6..713aae0 100644
--- a/migration.h
+++ b/migration.h
@@ -19,6 +19,7 @@
#include "notify.h"
#include "error.h"
#include "vmstate.h"
+#include "qapi-types.h"
struct MigrationParams {
bool blk;
@@ -39,6 +40,7 @@ struct MigrationState
void *opaque;
MigrationParams params;
int64_t total_time;
+ bool enabled_capabilities[MIGRATION_CAPABILITY_MAX];
};
void process_incoming_migration(QEMUFile *f);
diff --git a/monitor.c b/monitor.c
index 43f7df5..58d6e2a 100644
--- a/monitor.c
+++ b/monitor.c
@@ -2669,6 +2669,13 @@ static mon_cmd_t info_cmds[] = {
.mhandler.info = hmp_info_migration_supported_capabilities,
},
{
+ .name = "migrate_capabilities",
+ .args_type = "",
+ .params = "",
+ .help = "show current migration capabilities",
+ .mhandler.info = hmp_info_migrate_capabilities,
+ },
+ {
.name = "balloon",
.args_type = "",
.params = "",
diff --git a/qapi-schema.json b/qapi-schema.json
index 68d0fbb..f38dfc6 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -345,6 +345,38 @@
{ 'command': 'query-migration-supported-capabilities', 'returns': ['MigrationCapabilityStatus'] }
##
+# @migrate-set-capabilities
+#
+# Enable/Disable the following migration capabilities (like xbzrle)
+#
+# Since: 1.2
+##
+{ 'command': 'migrate-set-capabilities',
+ 'data': { 'capabilities': ['MigrationCapabilityStatus'] } }
+
+##
+# @MigrationParameters
+#
+# @capabilities: @MigrationCapabilityStatus list contain current migration
+# capabilities status
+# Since: 1.2
+##
+{ 'type': 'MigrationParameters',
+ 'data': {'capabilities': ['MigrationCapabilityStatus']} }
+
+
+##
+# @query-migrate-capabilities
+#
+# Returns information about the current migration capabilities status
+#
+# Returns: @MigrationCapabilitiesStatus
+#
+# Since: 1.2
+##
+{ 'command': 'query-migrate-capabilities', 'returns': ['MigrationCapabilityStatus']}
+
+##
# @MouseInfo:
#
# Information about a mouse device.
diff --git a/qmp-commands.hx b/qmp-commands.hx
index 16fbcef..0d527e4 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -2081,7 +2081,6 @@ The main json-object contains the following:
- "transferred": amount transferred (json-int)
- "remaining": amount remaining (json-int)
- "total": total (json-int)
-
Examples:
1. Before the first migration
@@ -2092,7 +2091,15 @@ Examples:
2. Migration is done and has succeeded
-> { "execute": "query-migrate" }
-<- { "return": { "status": "completed" } }
+<- { "return": {
+ "status": "completed",
+ "ram":{
+ "transferred":123,
+ "remaining":123,
+ "total":246
+ }
+ }
+ }
3. Migration is done and has failed
@@ -2166,6 +2173,55 @@ EQMP
},
SQMP
+migrate-set-capabilities
+-------
+
+Enable/Disable migration capabilities
+
+- "xbzrle": xbzrle support
+
+Arguments:
+
+Example:
+
+-> { "execute": "migrate-set-capabilities" , "arguments":
+ { "capabilities": [ { "capability": "xbzrle", "state": true } ] } }
+
+EQMP
+
+ {
+ .name = "migrate_set_capabilities",
+ .args_type = "capabilities:O",
+ .params = "capability:s,state:b",
+ .mhandler.cmd_new = qmp_marshal_input_migrate_set_capabilities,
+ },
+SQMP
+query-migrate-capabilities
+-------
+
+Query current migration capabilities
+
+- "capabilities": migration capabilities state
+ - "xbzrle" : XBZRLE state (json-bool)
+
+Arguments:
+
+Example:
+
+-> { "execute": "query-migrate-capabilities" }
+<- { "return": {
+ "capabilities" : [ { "capability" : "xbzrle", "state" : false } ]
+ }
+ }
+EQMP
+
+ {
+ .name = "query-migrate-capabilities",
+ .args_type = "",
+ .mhandler.cmd_new = qmp_marshal_input_query_migrate_capabilities,
+ },
+
+SQMP
query-balloon
-------------
--
1.7.7.6
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [Qemu-devel] [PATCH 03/11] Add XBZRLE documentation
2012-07-31 18:54 [Qemu-devel] [PATCH 00/11] Migration next v8 Orit Wasserman
2012-07-31 18:54 ` [Qemu-devel] [PATCH 01/11] Add migration capabilities Orit Wasserman
2012-07-31 18:54 ` [Qemu-devel] [PATCH 02/11] Add migrate_set_parameter and query-migrate-parameters Orit Wasserman
@ 2012-07-31 18:54 ` Orit Wasserman
2012-07-31 18:54 ` [Qemu-devel] [PATCH 04/11] Add cache handling functions Orit Wasserman
` (7 subsequent siblings)
10 siblings, 0 replies; 32+ messages in thread
From: Orit Wasserman @ 2012-07-31 18:54 UTC (permalink / raw)
To: qemu-devel
Cc: peter.maydell, aliguori, quintela, stefanha, mdroth, lcapitulino,
blauwirbel, Orit Wasserman, chegu_vinod, avi, pbonzini, eblake
Signed-off-by: Orit Wasserman <owasserm@redhat.com>
---
docs/xbzrle.txt | 136 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 136 insertions(+), 0 deletions(-)
create mode 100644 docs/xbzrle.txt
diff --git a/docs/xbzrle.txt b/docs/xbzrle.txt
new file mode 100644
index 0000000..1463c0a
--- /dev/null
+++ b/docs/xbzrle.txt
@@ -0,0 +1,136 @@
+XBZRLE (Xor Based Zero Run Length Encoding)
+===========================================
+
+Using XBZRLE (Xor Based Zero Run Length Encoding) allows for the reduction
+of VM downtime and the total live-migration time of Virtual machines.
+It is particularly useful for virtual machines running memory write intensive
+workloads that are typical of large enterprise applications such as SAP ERP
+Systems, and generally speaking for any application that uses a sparse memory
+update pattern.
+
+Instead of sending the changed guest memory page this solution will send a
+compressed version of the updates, thus reducing the amount of data sent during
+live migration.
+In order to be able to calculate the update, the previous memory pages need to
+be stored on the source. Those pages are stored in a dedicated cache
+(hash table) and are
+accessed by their address.
+The larger the cache size the better the chances are that the page has already
+been stored in the cache.
+A small cache size will result in high cache miss rate.
+Cache size can be changed before and during migration.
+
+Format
+=======
+
+The compression format performs a XOR between the previous and current content
+of the page, where zero represents an unchanged value.
+The page data delta is represented by zero and non zero runs.
+A zero run is represented by its length (in bytes).
+A non zero run is represented by its length (in bytes) and the new data.
+The run length is encoded using ULEB128 (http://en.wikipedia.org/wiki/LEB128)
+
+There can be more than one valid encoding, the sender may send a longer encoding
+for the benefit of reducing computation cost.
+
+page = zrun nzrun
+ | zrun nzrun page
+
+zrun = length
+
+nzrun = length byte...
+
+length = uleb128 encoded integer
+
+On the sender side XBZRLE is used as a compact delta encoding of page updates,
+retrieving the old page content from the cache (default size of 512 MB). The
+receiving side uses the existing page's content and XBZRLE to decode the new
+page's content.
+
+This work was originally based on research results published
+VEE 2011: Evaluation of Delta Compression Techniques for Efficient Live
+Migration of Large Virtual Machines by Benoit, Svard, Tordsson and Elmroth.
+Additionally the delta encoder XBRLE was improved further using the XBZRLE
+instead.
+
+XBZRLE has a sustained bandwidth of 2-2.5 GB/s for typical workloads making it
+ideal for in-line, real-time encoding such as is needed for live-migration.
+
+Example
+old buffer:
+1001 zeros
+05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 68 00 00 6b 00 6d
+3074 zeros
+
+new buffer:
+1001 zeros
+01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 68 00 00 67 00 69
+3074 zeros
+
+encoded buffer:
+
+encoded length 24
+e9 07 0f 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 03 01 67 01 01 69
+
+Migration Capabilities
+======================
+In order to use XBZRLE the destination QEMU version should be able to
+decode the new format.
+Adding a new migration capabilities command that will allow external management
+to query for it support.
+A typical use for the destination
+ {qemu} info migrate_supported_capabilities
+ {qemu} xbzrle, ...
+
+In order to enable capabilities for future live migration,
+a new command migrate_set_capability is introduced:
+ {qemu} migrate_set_capability xbzrle
+
+Usage
+======
+
+1. Activate xbzrle
+2. Set the XBZRLE cache size - the cache size is in MBytes and should be a
+power of 2. The cache default value is 64MBytes.
+3. start outgoing migration
+
+A typical usage scenario:
+On the incoming QEMU:
+ {qemu} migrate_set_capability xbzrle on
+On the outgoing QEMU:
+ {qemu} migrate_set_capability xbzrle on
+ {qemu} migrate_set_cachesize 256m
+ {qemu} migrate -d tcp:destination.host:4444
+ {qemu} info migrate
+ ...
+ cache size: 67108864 bytes
+ transferred ram-duplicate: A kbytes
+ transferred ram-normal: B kbytes
+ transferred ram-xbrle: C kbytes
+ overflow ram-xbrle: D pages
+ cache-miss ram-xbrle: E pages
+
+cache-miss: the number of cache misses to date - high cache-miss rate
+indicates that the cache size is set too low.
+overflow: the number of overflows in the decoding which where the delta could
+not be compressed. This can happen if the changes in the pages are too large
+or there are many short changes; for example, changing every second byte (half a
+page).
+
+Testing: Testing indicated that live migration with XBZRLE was completed in 110
+seconds, whereas without it would not be able to complete.
+
+A simple synthetic memory r/w load generator:
+.. include <stdlib.h>
+.. include <stdio.h>
+.. int main()
+.. {
+.. char *buf = (char *) calloc(4096, 4096);
+.. while (1) {
+.. int i;
+.. for (i = 0; i < 4096 * 4; i++) {
+.. buf[i * 4096 / 4]++;
+.. }
+.. printf(".");
+.. }
+.. }
--
1.7.7.6
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [Qemu-devel] [PATCH 04/11] Add cache handling functions
2012-07-31 18:54 [Qemu-devel] [PATCH 00/11] Migration next v8 Orit Wasserman
` (2 preceding siblings ...)
2012-07-31 18:54 ` [Qemu-devel] [PATCH 03/11] Add XBZRLE documentation Orit Wasserman
@ 2012-07-31 18:54 ` Orit Wasserman
2012-07-31 18:54 ` [Qemu-devel] [PATCH 05/11] Add uleb encoding/decoding functions Orit Wasserman
` (6 subsequent siblings)
10 siblings, 0 replies; 32+ messages in thread
From: Orit Wasserman @ 2012-07-31 18:54 UTC (permalink / raw)
To: qemu-devel
Cc: peter.maydell, aliguori, quintela, Petter Svard, stefanha, mdroth,
Benoit Hudzia, lcapitulino, blauwirbel, Orit Wasserman,
chegu_vinod, avi, Aidan Shribman, pbonzini, eblake
Add MRU page cache mechanism.
The page are accessed by their address.
Signed-off-by: Benoit Hudzia <benoit.hudzia@sap.com>
Signed-off-by: Petter Svard <petters@cs.umu.se>
Signed-off-by: Aidan Shribman <aidan.shribman@sap.com>
Signed-off-by: Orit Wasserman <owasserm@redhat.com>
---
Makefile.objs | 1 +
cutils.c | 9 ++
include/qemu/page_cache.h | 79 ++++++++++++++++
page_cache.c | 218 +++++++++++++++++++++++++++++++++++++++++++++
qemu-common.h | 13 +++
5 files changed, 320 insertions(+), 0 deletions(-)
create mode 100644 include/qemu/page_cache.h
create mode 100644 page_cache.c
diff --git a/Makefile.objs b/Makefile.objs
index 5ebbcfa..e0fb69b 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -77,6 +77,7 @@ common-obj-y += qemu-char.o #aio.o
common-obj-y += block-migration.o iohandler.o
common-obj-y += pflib.o
common-obj-y += bitmap.o bitops.o
+common-obj-y += page_cache.o
common-obj-$(CONFIG_POSIX) += migration-exec.o migration-unix.o migration-fd.o
common-obj-$(CONFIG_WIN32) += version.o
diff --git a/cutils.c b/cutils.c
index e2bc1b8..b0bdd4b 100644
--- a/cutils.c
+++ b/cutils.c
@@ -375,3 +375,12 @@ int qemu_parse_fd(const char *param)
}
return fd;
}
+
+/* round down to the nearest power of 2*/
+int64_t pow2floor(int64_t value)
+{
+ if (!is_power_of_2(value)) {
+ value = 0x8000000000000000ULL >> clz64(value);
+ }
+ return value;
+}
diff --git a/include/qemu/page_cache.h b/include/qemu/page_cache.h
new file mode 100644
index 0000000..3839ac7
--- /dev/null
+++ b/include/qemu/page_cache.h
@@ -0,0 +1,79 @@
+/*
+ * Page cache for QEMU
+ * The cache is base on a hash of the page address
+ *
+ * Copyright 2012 Red Hat, Inc. and/or its affiliates
+ *
+ * Authors:
+ * Orit Wasserman <owasserm@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef PAGE_CACHE_H
+#define PAGE_CACHE_H
+
+/* Page cache for storing guest pages */
+typedef struct PageCache PageCache;
+
+/**
+ * cache_init: Initialize the page cache
+ *
+ *
+ * Returns new allocated cache or NULL on error
+ *
+ * @cache pointer to the PageCache struct
+ * @num_pages: cache maximal number of cached pages
+ * @page_size: cache page size
+ */
+PageCache *cache_init(int64_t num_pages, unsigned int page_size);
+
+/**
+ * cache_fini: free all cache resources
+ * @cache pointer to the PageCache struct
+ */
+void cache_fini(PageCache *cache);
+
+/**
+ * cache_is_cached: Checks to see if the page is cached
+ *
+ * Returns %true if page is cached
+ *
+ * @cache pointer to the PageCache struct
+ * @addr: page addr
+ */
+bool cache_is_cached(const PageCache *cache, uint64_t addr);
+
+/**
+ * get_cached_data: Get the data cached for an addr
+ *
+ * Returns pointer to the data cached or NULL if not cached
+ *
+ * @cache pointer to the PageCache struct
+ * @addr: page addr
+ */
+uint8_t *get_cached_data(const PageCache *cache, uint64_t addr);
+
+/**
+ * cache_insert: insert the page into the cache. the previous value will be overwritten
+ *
+ * @cache pointer to the PageCache struct
+ * @addr: page address
+ * @pdata: pointer to the page
+ */
+void cache_insert(PageCache *cache, uint64_t addr, uint8_t *pdata);
+
+/**
+ * cache_resize: resize the page cache. In case of size reduction the extra
+ * pages will be freed
+ *
+ * Returns -1 on error new cache size on success
+ *
+ * @cache pointer to the PageCache struct
+ * @num_pages: new page cache size (in pages)
+ */
+int64_t cache_resize(PageCache *cache, int64_t num_pages);
+
+#endif
diff --git a/page_cache.c b/page_cache.c
new file mode 100644
index 0000000..0294f7e
--- /dev/null
+++ b/page_cache.c
@@ -0,0 +1,218 @@
+/*
+ * Page cache for QEMU
+ * The cache is base on a hash of the page address
+ *
+ * Copyright 2012 Red Hat, Inc. and/or its affiliates
+ *
+ * Authors:
+ * Orit Wasserman <owasserm@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+#include <string.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <stdbool.h>
+#include <glib.h>
+#include <strings.h>
+
+#include "qemu-common.h"
+#include "qemu/page_cache.h"
+
+#ifdef DEBUG_CACHE
+#define DPRINTF(fmt, ...) \
+ do { fprintf(stdout, "cache: " fmt, ## __VA_ARGS__); } while (0)
+#else
+#define DPRINTF(fmt, ...) \
+ do { } while (0)
+#endif
+
+typedef struct CacheItem CacheItem;
+
+struct CacheItem {
+ uint64_t it_addr;
+ uint64_t it_age;
+ uint8_t *it_data;
+};
+
+struct PageCache {
+ CacheItem *page_cache;
+ unsigned int page_size;
+ int64_t max_num_items;
+ uint64_t max_item_age;
+ int64_t num_items;
+};
+
+PageCache *cache_init(int64_t num_pages, unsigned int page_size)
+{
+ int64_t i;
+
+ PageCache *cache;
+
+ if (num_pages <= 0) {
+ DPRINTF("invalid number of pages\n");
+ return NULL;
+ }
+
+ cache = g_malloc(sizeof(*cache));
+
+ /* round down to the nearest power of 2 */
+ if (!is_power_of_2(num_pages)) {
+ num_pages = pow2floor(num_pages);
+ DPRINTF("rounding down to %" PRId64 "\n", num_pages);
+ }
+ cache->page_size = page_size;
+ cache->num_items = 0;
+ cache->max_item_age = 0;
+ cache->max_num_items = num_pages;
+
+ DPRINTF("Setting cache buckets to %" PRId64 "\n", cache->max_num_items);
+
+ cache->page_cache = g_malloc((cache->max_num_items) *
+ sizeof(*cache->page_cache));
+
+ for (i = 0; i < cache->max_num_items; i++) {
+ cache->page_cache[i].it_data = NULL;
+ cache->page_cache[i].it_age = 0;
+ cache->page_cache[i].it_addr = -1;
+ }
+
+ return cache;
+}
+
+void cache_fini(PageCache *cache)
+{
+ int64_t i;
+
+ g_assert(cache);
+ g_assert(cache->page_cache);
+
+ for (i = 0; i < cache->max_num_items; i++) {
+ g_free(cache->page_cache[i].it_data);
+ }
+
+ g_free(cache->page_cache);
+ cache->page_cache = NULL;
+}
+
+static size_t cache_get_cache_pos(const PageCache *cache,
+ uint64_t address)
+{
+ size_t pos;
+
+ g_assert(cache->max_num_items);
+ pos = (address / cache->page_size) & (cache->max_num_items - 1);
+ return pos;
+}
+
+bool cache_is_cached(const PageCache *cache, uint64_t addr)
+{
+ size_t pos;
+
+ g_assert(cache);
+ g_assert(cache->page_cache);
+
+ pos = cache_get_cache_pos(cache, addr);
+
+ return (cache->page_cache[pos].it_addr == addr);
+}
+
+static CacheItem *cache_get_by_addr(const PageCache *cache, uint64_t addr)
+{
+ size_t pos;
+
+ g_assert(cache);
+ g_assert(cache->page_cache);
+
+ pos = cache_get_cache_pos(cache, addr);
+
+ return &cache->page_cache[pos];
+}
+
+uint8_t *get_cached_data(const PageCache *cache, uint64_t addr)
+{
+ return cache_get_by_addr(cache, addr)->it_data;
+}
+
+void cache_insert(PageCache *cache, uint64_t addr, uint8_t *pdata)
+{
+
+ CacheItem *it = NULL;
+
+ g_assert(cache);
+ g_assert(cache->page_cache);
+
+ /* actual update of entry */
+ it = cache_get_by_addr(cache, addr);
+
+ if (!it->it_data) {
+ cache->num_items++;
+ }
+
+ it->it_data = pdata;
+ it->it_age = ++cache->max_item_age;
+ it->it_addr = addr;
+}
+
+int64_t cache_resize(PageCache *cache, int64_t new_num_pages)
+{
+ PageCache *new_cache;
+ int64_t i;
+
+ CacheItem *old_it, *new_it;
+
+ g_assert(cache);
+
+ /* cache was not inited */
+ if (cache->page_cache == NULL) {
+ return -1;
+ }
+
+ /* same size */
+ if (pow2floor(new_num_pages) == cache->max_num_items) {
+ return cache->max_num_items;
+ }
+
+ new_cache = cache_init(new_num_pages, cache->page_size);
+ if (!(new_cache)) {
+ DPRINTF("Error creating new cache\n");
+ return -1;
+ }
+
+ /* move all data from old cache */
+ for (i = 0; i < cache->max_num_items; i++) {
+ old_it = &cache->page_cache[i];
+ if (old_it->it_addr != -1) {
+ /* check for collision, if there is, keep MRU page */
+ new_it = cache_get_by_addr(new_cache, old_it->it_addr);
+ if (new_it->it_data) {
+ /* keep the MRU page */
+ if (new_it->it_age >= old_it->it_age) {
+ g_free(old_it->it_data);
+ } else {
+ g_free(new_it->it_data);
+ new_it->it_data = old_it->it_data;
+ new_it->it_age = old_it->it_age;
+ new_it->it_addr = old_it->it_addr;
+ }
+ } else {
+ cache_insert(new_cache, old_it->it_addr, old_it->it_data);
+ }
+ }
+ }
+
+ cache->page_cache = new_cache->page_cache;
+ cache->max_num_items = new_cache->max_num_items;
+ cache->num_items = new_cache->num_items;
+
+ g_free(new_cache);
+
+ return cache->max_num_items;
+}
diff --git a/qemu-common.h b/qemu-common.h
index 09676f5..855f242 100644
--- a/qemu-common.h
+++ b/qemu-common.h
@@ -1,3 +1,4 @@
+
/* Common header file that is included by all of qemu. */
#ifndef QEMU_COMMON_H
#define QEMU_COMMON_H
@@ -411,6 +412,18 @@ static inline uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
/* Round number up to multiple */
#define QEMU_ALIGN_UP(n, m) QEMU_ALIGN_DOWN((n) + (m) - 1, (m))
+static inline bool is_power_of_2(uint64_t value)
+{
+ if (!value) {
+ return 0;
+ }
+
+ return !(value & (value - 1));
+}
+
+/* round down to the nearest power of 2*/
+int64_t pow2floor(int64_t value);
+
#include "module.h"
#endif
--
1.7.7.6
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [Qemu-devel] [PATCH 05/11] Add uleb encoding/decoding functions
2012-07-31 18:54 [Qemu-devel] [PATCH 00/11] Migration next v8 Orit Wasserman
` (3 preceding siblings ...)
2012-07-31 18:54 ` [Qemu-devel] [PATCH 04/11] Add cache handling functions Orit Wasserman
@ 2012-07-31 18:54 ` Orit Wasserman
2012-07-31 18:54 ` [Qemu-devel] [PATCH 06/11] Add xbzrle_encode_buffer and xbzrle_decode_buffer functions Orit Wasserman
` (5 subsequent siblings)
10 siblings, 0 replies; 32+ messages in thread
From: Orit Wasserman @ 2012-07-31 18:54 UTC (permalink / raw)
To: qemu-devel
Cc: peter.maydell, aliguori, quintela, stefanha, mdroth, lcapitulino,
blauwirbel, Orit Wasserman, chegu_vinod, avi, pbonzini, eblake
Implement Unsigned Little Endian Base 128.
Signed-off-by: Orit Wasserman <owasserm@redhat.com>
---
cutils.c | 33 +++++++++++++++++++++++++++++++++
qemu-common.h | 8 ++++++++
2 files changed, 41 insertions(+), 0 deletions(-)
diff --git a/cutils.c b/cutils.c
index b0bdd4b..700f943 100644
--- a/cutils.c
+++ b/cutils.c
@@ -384,3 +384,36 @@ int64_t pow2floor(int64_t value)
}
return value;
}
+
+/*
+ * Implementation of ULEB128 (http://en.wikipedia.org/wiki/LEB128)
+ * Input is limited to 14-bit numbers
+ */
+int uleb128_encode_small(uint8_t *out, uint32_t n)
+{
+ g_assert(n <= 0x3fff);
+ if (n < 0x80) {
+ *out++ = n;
+ return 1;
+ } else {
+ *out++ = (n & 0x7f) | 0x80;
+ *out++ = n >> 7;
+ return 2;
+ }
+}
+
+int uleb128_decode_small(const uint8_t *in, uint32_t *n)
+{
+ if (!(*in & 0x80)) {
+ *n = *in++;
+ return 1;
+ } else {
+ *n = *in++ & 0x7f;
+ /* we exceed 14 bit number */
+ if (*in & 0x80) {
+ return -1;
+ }
+ *n |= *in++ << 7;
+ return 2;
+ }
+}
diff --git a/qemu-common.h b/qemu-common.h
index 855f242..93d1c63 100644
--- a/qemu-common.h
+++ b/qemu-common.h
@@ -426,4 +426,12 @@ int64_t pow2floor(int64_t value);
#include "module.h"
+/*
+ * Implementation of ULEB128 (http://en.wikipedia.org/wiki/LEB128)
+ * Input is limited to 14-bit numbers
+ */
+
+int uleb128_encode_small(uint8_t *out, uint32_t n);
+int uleb128_decode_small(const uint8_t *in, uint32_t *n);
+
#endif
--
1.7.7.6
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [Qemu-devel] [PATCH 06/11] Add xbzrle_encode_buffer and xbzrle_decode_buffer functions
2012-07-31 18:54 [Qemu-devel] [PATCH 00/11] Migration next v8 Orit Wasserman
` (4 preceding siblings ...)
2012-07-31 18:54 ` [Qemu-devel] [PATCH 05/11] Add uleb encoding/decoding functions Orit Wasserman
@ 2012-07-31 18:54 ` Orit Wasserman
2012-07-31 18:54 ` [Qemu-devel] [PATCH 07/11] Add XBZRLE to ram_save_block and ram_save_live Orit Wasserman
` (4 subsequent siblings)
10 siblings, 0 replies; 32+ messages in thread
From: Orit Wasserman @ 2012-07-31 18:54 UTC (permalink / raw)
To: qemu-devel
Cc: peter.maydell, aliguori, quintela, Petter Svard, stefanha, mdroth,
Benoit Hudzia, lcapitulino, blauwirbel, Orit Wasserman,
chegu_vinod, avi, Aidan Shribman, pbonzini, eblake
For performance we are encoding long word at a time.
For nzrun we use long-word-at-a-time NULL-detection tricks from strcmp():
using ((lword - 0x0101010101010101) & (~lword) & 0x8080808080808080) test
to find out if any byte in the long word is zero.
Signed-off-by: Benoit Hudzia <benoit.hudzia@sap.com>
Signed-off-by: Petter Svard <petters@cs.umu.se>
Signed-off-by: Aidan Shribman <aidan.shribman@sap.com>
Signed-off-by: Orit Wasserman <owasserm@redhat.com>
Signed-off-by: Eric Blake <eblake@redhat.com>
---
migration.h | 4 ++
savevm.c | 159 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 163 insertions(+), 0 deletions(-)
diff --git a/migration.h b/migration.h
index 713aae0..743c366 100644
--- a/migration.h
+++ b/migration.h
@@ -100,4 +100,8 @@ void migrate_add_blocker(Error *reason);
*/
void migrate_del_blocker(Error *reason);
+int xbzrle_encode_buffer(uint8_t *old_buf, uint8_t *new_buf, int slen,
+ uint8_t *dst, int dlen);
+int xbzrle_decode_buffer(uint8_t *src, int slen, uint8_t *dst, int dlen);
+
#endif
diff --git a/savevm.c b/savevm.c
index 6e82b2d..0ea10c9 100644
--- a/savevm.c
+++ b/savevm.c
@@ -2392,3 +2392,162 @@ void vmstate_register_ram_global(MemoryRegion *mr)
{
vmstate_register_ram(mr, NULL);
}
+
+/*
+ page = zrun nzrun
+ | zrun nzrun page
+
+ zrun = length
+
+ nzrun = length byte...
+
+ length = uleb128 encoded integer
+ */
+int xbzrle_encode_buffer(uint8_t *old_buf, uint8_t *new_buf, int slen,
+ uint8_t *dst, int dlen)
+{
+ uint32_t zrun_len = 0, nzrun_len = 0;
+ int d = 0, i = 0;
+ long res, xor;
+ uint8_t *nzrun_start = NULL;
+
+ g_assert(!(((uintptr_t)old_buf | (uintptr_t)new_buf | slen) %
+ sizeof(long)));
+
+ while (i < slen) {
+ /* overflow */
+ if (d + 2 > dlen) {
+ return -1;
+ }
+
+ /* not aligned to sizeof(long) */
+ res = (slen - i) % sizeof(long);
+ while (res && old_buf[i] == new_buf[i]) {
+ zrun_len++;
+ i++;
+ res--;
+ }
+
+ /* word at a time for speed */
+ if (!res) {
+ while (i < slen &&
+ (*(long *)(old_buf + i)) == (*(long *)(new_buf + i))) {
+ i += sizeof(long);
+ zrun_len += sizeof(long);
+ }
+
+ /* go over the rest */
+ while (i < slen && old_buf[i] == new_buf[i]) {
+ zrun_len++;
+ i++;
+ }
+ }
+
+ /* buffer unchanged */
+ if (zrun_len == slen) {
+ return 0;
+ }
+
+ /* skip last zero run */
+ if (i == slen) {
+ return d;
+ }
+
+ d += uleb128_encode_small(dst + d, zrun_len);
+
+ zrun_len = 0;
+ nzrun_start = new_buf + i;
+
+ /* overflow */
+ if (d + 2 > dlen) {
+ return -1;
+ }
+ /* not aligned to sizeof(long) */
+ res = (slen - i) % sizeof(long);
+ while (res && old_buf[i] != new_buf[i]) {
+ i++;
+ nzrun_len++;
+ res--;
+ }
+
+ /* word at a time for speed, use of 32-bit long okay */
+ if (!res) {
+ /* truncation to 32-bit long okay */
+ long mask = 0x0101010101010101ULL;
+ while (i < slen) {
+ xor = *(long *)(old_buf + i) ^ *(long *)(new_buf + i);
+ if ((xor - mask) & ~xor & (mask << 7)) {
+ /* found the end of an nzrun within the current long */
+ while (old_buf[i] != new_buf[i]) {
+ nzrun_len++;
+ i++;
+ }
+ break;
+ } else {
+ i += sizeof(long);
+ nzrun_len += sizeof(long);
+ }
+ }
+ }
+
+ d += uleb128_encode_small(dst + d, nzrun_len);
+ /* overflow */
+ if (d + nzrun_len > dlen) {
+ return -1;
+ }
+ memcpy(dst + d, nzrun_start, nzrun_len);
+ d += nzrun_len;
+ nzrun_len = 0;
+ }
+
+ return d;
+}
+
+int xbzrle_decode_buffer(uint8_t *src, int slen, uint8_t *dst, int dlen)
+{
+ int i = 0, d = 0;
+ int ret;
+ uint32_t count = 0;
+
+ while (i < slen) {
+
+ /* zrun */
+ if ((slen - i) < 2) {
+ return -1;
+ }
+
+ ret = uleb128_decode_small(src + i, &count);
+ if (ret < 0 || (i && !count)) {
+ return -1;
+ }
+ i += ret;
+ d += count;
+
+ /* overflow */
+ if (d > dlen) {
+ return -1;
+ }
+
+ /* nzrun */
+ if ((slen - i) < 2) {
+ return -1;
+ }
+
+ ret = uleb128_decode_small(src + i, &count);
+ if (ret < 0 || !count) {
+ return -1;
+ }
+ i += ret;
+
+ /* overflow */
+ if (d + count > dlen || i + count > slen) {
+ return -1;
+ }
+
+ memcpy(dst + d, src + i, count);
+ d += count;
+ i += count;
+ }
+
+ return d;
+}
--
1.7.7.6
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [Qemu-devel] [PATCH 07/11] Add XBZRLE to ram_save_block and ram_save_live
2012-07-31 18:54 [Qemu-devel] [PATCH 00/11] Migration next v8 Orit Wasserman
` (5 preceding siblings ...)
2012-07-31 18:54 ` [Qemu-devel] [PATCH 06/11] Add xbzrle_encode_buffer and xbzrle_decode_buffer functions Orit Wasserman
@ 2012-07-31 18:54 ` Orit Wasserman
2012-07-31 18:54 ` [Qemu-devel] [PATCH 08/11] Add migrate_set_cachesize command Orit Wasserman
` (3 subsequent siblings)
10 siblings, 0 replies; 32+ messages in thread
From: Orit Wasserman @ 2012-07-31 18:54 UTC (permalink / raw)
To: qemu-devel
Cc: peter.maydell, aliguori, quintela, Petter Svard, stefanha, mdroth,
Benoit Hudzia, lcapitulino, blauwirbel, Orit Wasserman,
chegu_vinod, avi, Aidan Shribman, pbonzini, eblake
In the outgoing migration check to see if the page is cached and
changed, then send compressed page by using save_xbrle_page function.
In the incoming migration check to see if RAM_SAVE_FLAG_XBZRLE is set
and decompress the page (by using load_xbrle function).
Signed-off-by: Benoit Hudzia <benoit.hudzia@sap.com>
Signed-off-by: Petter Svard <petters@cs.umu.se>
Signed-off-by: Aidan Shribman <aidan.shribman@sap.com>
Signed-off-by: Orit Wasserman <owasserm@redhat.com>
---
arch_init.c | 158 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
migration.c | 24 +++++++++
migration.h | 4 ++
3 files changed, 184 insertions(+), 2 deletions(-)
diff --git a/arch_init.c b/arch_init.c
index 78cdf50..410ba4d 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -43,6 +43,7 @@
#include "hw/smbios.h"
#include "exec-memory.h"
#include "hw/pcspk.h"
+#include "qemu/page_cache.h"
#ifdef DEBUG_ARCH_INIT
#define DPRINTF(fmt, ...) \
@@ -102,6 +103,7 @@ const uint32_t arch_type = QEMU_ARCH;
#define RAM_SAVE_FLAG_PAGE 0x08
#define RAM_SAVE_FLAG_EOS 0x10
#define RAM_SAVE_FLAG_CONTINUE 0x20
+#define RAM_SAVE_FLAG_XBZRLE 0x40
#ifdef __ALTIVEC__
#include <altivec.h>
@@ -169,6 +171,24 @@ static int is_dup_page(uint8_t *page)
return 1;
}
+/* struct contains XBZRLE cache and a static page
+ used by the compression */
+static struct {
+ /* buffer used for XBZRLE encoding */
+ uint8_t *encoded_buf;
+ /* buffer for storing page content */
+ uint8_t *current_buf;
+ /* buffer used for XBZRLE decoding */
+ uint8_t *decoded_buf;
+ /* Cache for XBZRLE */
+ PageCache *cache;
+} XBZRLE = {
+ .encoded_buf = NULL,
+ .current_buf = NULL,
+ .decoded_buf = NULL,
+ .cache = NULL,
+};
+
static void save_block_hdr(QEMUFile *f, RAMBlock *block, ram_addr_t offset,
int cont, int flag)
{
@@ -181,6 +201,53 @@ static void save_block_hdr(QEMUFile *f, RAMBlock *block, ram_addr_t offset,
}
+#define ENCODING_FLAG_XBZRLE 0x1
+
+static int save_xbzrle_page(QEMUFile *f, uint8_t *current_data,
+ ram_addr_t current_addr, RAMBlock *block,
+ ram_addr_t offset, int cont)
+{
+ int encoded_len = 0, bytes_sent = -1;
+ uint8_t *prev_cached_page;
+
+ if (!cache_is_cached(XBZRLE.cache, current_addr)) {
+ cache_insert(XBZRLE.cache, current_addr,
+ g_memdup(current_data, TARGET_PAGE_SIZE));
+ return -1;
+ }
+
+ prev_cached_page = get_cached_data(XBZRLE.cache, current_addr);
+
+ /* save current buffer into memory */
+ memcpy(XBZRLE.current_buf, current_data, TARGET_PAGE_SIZE);
+
+ /* XBZRLE encoding (if there is no overflow) */
+ encoded_len = xbzrle_encode_buffer(prev_cached_page, XBZRLE.current_buf,
+ TARGET_PAGE_SIZE, XBZRLE.encoded_buf,
+ TARGET_PAGE_SIZE);
+ if (encoded_len == 0) {
+ DPRINTF("Skipping unmodified page\n");
+ return 0;
+ } else if (encoded_len == -1) {
+ DPRINTF("Overflow\n");
+ /* update data in the cache */
+ memcpy(prev_cached_page, current_data, TARGET_PAGE_SIZE);
+ return -1;
+ }
+
+ /* we need to update the data in the cache, in order to get the same data */
+ memcpy(prev_cached_page, XBZRLE.current_buf, TARGET_PAGE_SIZE);
+
+ /* Send XBZRLE based compressed page */
+ save_block_hdr(f, block, offset, cont, RAM_SAVE_FLAG_XBZRLE);
+ qemu_put_byte(f, ENCODING_FLAG_XBZRLE);
+ qemu_put_be16(f, encoded_len);
+ qemu_put_buffer(f, XBZRLE.encoded_buf, encoded_len);
+ bytes_sent = encoded_len + 1 + 2;
+
+ return bytes_sent;
+}
+
static RAMBlock *last_block;
static ram_addr_t last_offset;
@@ -198,6 +265,7 @@ static int ram_save_block(QEMUFile *f)
ram_addr_t offset = last_offset;
int bytes_sent = -1;
MemoryRegion *mr;
+ ram_addr_t current_addr;
if (!block)
block = QLIST_FIRST(&ram_list.blocks);
@@ -218,13 +286,24 @@ static int ram_save_block(QEMUFile *f)
save_block_hdr(f, block, offset, cont, RAM_SAVE_FLAG_COMPRESS);
qemu_put_byte(f, *p);
bytes_sent = 1;
- } else {
+ } else if (migrate_use_xbzrle()) {
+ current_addr = block->offset + offset;
+ bytes_sent = save_xbzrle_page(f, p, current_addr, block,
+ offset, cont);
+ p = get_cached_data(XBZRLE.cache, current_addr);
+ }
+
+ /* either we didn't send yet (we may have had XBZRLE overflow) */
+ if (bytes_sent == -1) {
save_block_hdr(f, block, offset, cont, RAM_SAVE_FLAG_PAGE);
qemu_put_buffer(f, p, TARGET_PAGE_SIZE);
bytes_sent = TARGET_PAGE_SIZE;
}
- break;
+ /* if page is unmodified, continue to the next */
+ if (bytes_sent != 0) {
+ break;
+ }
}
offset += TARGET_PAGE_SIZE;
@@ -302,6 +381,15 @@ static void sort_ram_list(void)
static void migration_end(void)
{
memory_global_dirty_log_stop();
+
+ if (migrate_use_xbzrle()) {
+ cache_fini(XBZRLE.cache);
+ g_free(XBZRLE.cache);
+ g_free(XBZRLE.encoded_buf);
+ g_free(XBZRLE.current_buf);
+ g_free(XBZRLE.decoded_buf);
+ XBZRLE.cache = NULL;
+ }
}
static void ram_migration_cancel(void *opaque)
@@ -321,6 +409,18 @@ static int ram_save_setup(QEMUFile *f, void *opaque)
last_offset = 0;
sort_ram_list();
+ if (migrate_use_xbzrle()) {
+ XBZRLE.cache = cache_init(migrate_xbzrle_cache_size() /
+ TARGET_PAGE_SIZE,
+ TARGET_PAGE_SIZE);
+ if (!XBZRLE.cache) {
+ DPRINTF("Error creating cache\n");
+ return -1;
+ }
+ XBZRLE.encoded_buf = g_malloc0(TARGET_PAGE_SIZE);
+ XBZRLE.current_buf = g_malloc(TARGET_PAGE_SIZE);
+ }
+
/* Make sure all dirty bits are set */
QLIST_FOREACH(block, &ram_list.blocks, next) {
for (addr = 0; addr < block->length; addr += TARGET_PAGE_SIZE) {
@@ -436,6 +536,47 @@ static int ram_save_complete(QEMUFile *f, void *opaque)
return 0;
}
+static int load_xbzrle(QEMUFile *f, ram_addr_t addr, void *host)
+{
+ int ret, rc = 0;
+ unsigned int xh_len;
+ int xh_flags;
+
+ if (!XBZRLE.decoded_buf) {
+ XBZRLE.decoded_buf = g_malloc(TARGET_PAGE_SIZE);
+ }
+
+ /* extract RLE header */
+ xh_flags = qemu_get_byte(f);
+ xh_len = qemu_get_be16(f);
+
+ if (xh_flags != ENCODING_FLAG_XBZRLE) {
+ fprintf(stderr, "Failed to load XBZRLE page - wrong compression!\n");
+ return -1;
+ }
+
+ if (xh_len > TARGET_PAGE_SIZE) {
+ fprintf(stderr, "Failed to load XBZRLE page - len overflow!\n");
+ return -1;
+ }
+ /* load data and decode */
+ qemu_get_buffer(f, XBZRLE.decoded_buf, xh_len);
+
+ /* decode RLE */
+ ret = xbzrle_decode_buffer(XBZRLE.decoded_buf, xh_len, host,
+ TARGET_PAGE_SIZE);
+ if (ret == -1) {
+ fprintf(stderr, "Failed to load XBZRLE page - decode error!\n");
+ rc = -1;
+ } else if (ret > TARGET_PAGE_SIZE) {
+ fprintf(stderr, "Failed to load XBZRLE page - size %d exceeds %d!\n",
+ ret, TARGET_PAGE_SIZE);
+ abort();
+ }
+
+ return rc;
+}
+
static inline void *host_from_stream_offset(QEMUFile *f,
ram_addr_t offset,
int flags)
@@ -549,6 +690,19 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id)
}
qemu_get_buffer(f, host, TARGET_PAGE_SIZE);
+ } else if (flags & RAM_SAVE_FLAG_XBZRLE) {
+ if (!migrate_use_xbzrle()) {
+ return -EINVAL;
+ }
+ void *host = host_from_stream_offset(f, addr, flags);
+ if (!host) {
+ return -EINVAL;
+ }
+
+ if (load_xbzrle(f, addr, host) < 0) {
+ ret = -EINVAL;
+ goto done;
+ }
}
error = qemu_file_get_error(f);
if (error) {
diff --git a/migration.c b/migration.c
index 4b52f36..48a5270 100644
--- a/migration.c
+++ b/migration.c
@@ -43,6 +43,9 @@ enum {
#define MAX_THROTTLE (32 << 20) /* Migration speed throttling */
+/* Migration XBZRLE default cache size */
+#define DEFAULT_MIGRATE_CACHE_SIZE (64 * 1024 * 1024)
+
static NotifierList migration_state_notifiers =
NOTIFIER_LIST_INITIALIZER(migration_state_notifiers);
@@ -55,6 +58,7 @@ static MigrationState *migrate_get_current(void)
static MigrationState current_migration = {
.state = MIG_STATE_SETUP,
.bandwidth_limit = MAX_THROTTLE,
+ .xbzrle_cache_size = DEFAULT_MIGRATE_CACHE_SIZE,
};
return ¤t_migration;
@@ -423,6 +427,7 @@ 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];
+ int64_t xbzrle_cache_size = s->xbzrle_cache_size;
memcpy(enabled_capabilities, s->enabled_capabilities,
sizeof(enabled_capabilities));
@@ -432,6 +437,7 @@ static MigrationState *migrate_init(const MigrationParams *params)
s->params = *params;
memcpy(s->enabled_capabilities, enabled_capabilities,
sizeof(enabled_capabilities));
+ s->xbzrle_cache_size = xbzrle_cache_size;
s->bandwidth_limit = bandwidth_limit;
s->state = MIG_STATE_SETUP;
@@ -531,3 +537,21 @@ void qmp_migrate_set_downtime(double value, Error **errp)
value = MAX(0, MIN(UINT64_MAX, value));
max_downtime = (uint64_t)value;
}
+
+int migrate_use_xbzrle(void)
+{
+ MigrationState *s;
+
+ s = migrate_get_current();
+
+ return s->enabled_capabilities[MIGRATION_CAPABILITY_XBZRLE];
+}
+
+int64_t migrate_xbzrle_cache_size(void)
+{
+ MigrationState *s;
+
+ s = migrate_get_current();
+
+ return s->xbzrle_cache_size;
+}
diff --git a/migration.h b/migration.h
index 743c366..cdf6787 100644
--- a/migration.h
+++ b/migration.h
@@ -41,6 +41,7 @@ struct MigrationState
MigrationParams params;
int64_t total_time;
bool enabled_capabilities[MIGRATION_CAPABILITY_MAX];
+ int64_t xbzrle_cache_size;
};
void process_incoming_migration(QEMUFile *f);
@@ -104,4 +105,7 @@ int xbzrle_encode_buffer(uint8_t *old_buf, uint8_t *new_buf, int slen,
uint8_t *dst, int dlen);
int xbzrle_decode_buffer(uint8_t *src, int slen, uint8_t *dst, int dlen);
+int migrate_use_xbzrle(void);
+int64_t migrate_xbzrle_cache_size(void);
+
#endif
--
1.7.7.6
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [Qemu-devel] [PATCH 08/11] Add migrate_set_cachesize command
2012-07-31 18:54 [Qemu-devel] [PATCH 00/11] Migration next v8 Orit Wasserman
` (6 preceding siblings ...)
2012-07-31 18:54 ` [Qemu-devel] [PATCH 07/11] Add XBZRLE to ram_save_block and ram_save_live Orit Wasserman
@ 2012-07-31 18:54 ` Orit Wasserman
2012-07-31 18:54 ` [Qemu-devel] [PATCH 09/11] Add migration accounting for normal and duplicate pages Orit Wasserman
` (2 subsequent siblings)
10 siblings, 0 replies; 32+ messages in thread
From: Orit Wasserman @ 2012-07-31 18:54 UTC (permalink / raw)
To: qemu-devel
Cc: peter.maydell, aliguori, quintela, Petter Svard, stefanha, mdroth,
Benoit Hudzia, lcapitulino, blauwirbel, Orit Wasserman,
chegu_vinod, avi, Aidan Shribman, pbonzini, eblake
Change XBZRLE cache size in bytes (the size should be a power of 2, it will be
rounded down to the nearest power of 2).
If XBZRLE cache size is too small there will be many cache miss.
New query-migrate-cache-size QMP command and 'info migrate-cache-size' HMP
command to query cache value.
Signed-off-by: Benoit Hudzia <benoit.hudzia@sap.com>
Signed-off-by: Petter Svard <petters@cs.umu.se>
Signed-off-by: Aidan Shribman <aidan.shribman@sap.com>
Signed-off-by: Orit Wasserman <owasserm@redhat.com>
---
arch_init.c | 10 ++++++++++
hmp-commands.hx | 22 ++++++++++++++++++++++
hmp.c | 19 +++++++++++++++++++
hmp.h | 2 ++
migration.c | 19 +++++++++++++++++++
migration.h | 2 ++
monitor.c | 7 +++++++
qapi-schema.json | 27 +++++++++++++++++++++++++++
qmp-commands.hx | 44 ++++++++++++++++++++++++++++++++++++++++++++
9 files changed, 152 insertions(+), 0 deletions(-)
diff --git a/arch_init.c b/arch_init.c
index 410ba4d..d709ccb 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -189,6 +189,16 @@ static struct {
.cache = NULL,
};
+
+int64_t xbzrle_cache_resize(int64_t new_size)
+{
+ if (XBZRLE.cache != NULL) {
+ return cache_resize(XBZRLE.cache, new_size / TARGET_PAGE_SIZE) *
+ TARGET_PAGE_SIZE;
+ }
+ return pow2floor(new_size);
+}
+
static void save_block_hdr(QEMUFile *f, RAMBlock *block, ram_addr_t offset,
int cont, int flag)
{
diff --git a/hmp-commands.hx b/hmp-commands.hx
index f4c8495..ae98c12 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -829,6 +829,26 @@ STEXI
@item migrate_cancel
@findex migrate_cancel
Cancel the current VM migration.
+
+ETEXI
+
+ {
+ .name = "migrate_set_cachesize",
+ .args_type = "value:o",
+ .params = "value",
+ .help = "set cache size (in bytes) for XBZRLE migrations,"
+ "the cache size will be rounded down to the nearest "
+ "power of 2.\n"
+ "The cache size affects the number of cache misses."
+ "In case of a high cache miss ratio you need to increase"
+ " the cache size",
+ .mhandler.cmd = hmp_migrate_set_cachesize,
+ },
+
+STEXI
+@item migrate_set_cachesize @var{value}
+@findex migrate_set_cachesize
+Set cache size to @var{value} (in bytes) for xbzrle migrations.
ETEXI
{
@@ -1435,6 +1455,8 @@ show migration status
show migration supported capabilities
@item info migrate_capabilities
show current migration capabilities
+@item info migrate-cache-size
+show current migration XBZRLE cache size
@item info balloon
show balloon information
@item info qtree
diff --git a/hmp.c b/hmp.c
index 463b730..3a61da5 100644
--- a/hmp.c
+++ b/hmp.c
@@ -215,6 +215,12 @@ void hmp_info_migrate_capabilities(Monitor *mon)
qapi_free_MigrationCapabilityStatusList(caps);
}
+void hmp_info_migrate_cache_size(Monitor *mon)
+{
+ monitor_printf(mon, "xbzrel cache size: %" PRId64 " kbytes\n",
+ qmp_query_migrate_cache_size(NULL) >> 10);
+}
+
void hmp_info_cpus(Monitor *mon)
{
CpuInfoList *cpu_list, *cpu;
@@ -783,6 +789,19 @@ void hmp_migrate_set_downtime(Monitor *mon, const QDict *qdict)
qmp_migrate_set_downtime(value, NULL);
}
+void hmp_migrate_set_cachesize(Monitor *mon, const QDict *qdict)
+{
+ int64_t value = qdict_get_int(qdict, "value");
+ Error *err = NULL;
+
+ qmp_migrate_set_cache_size(value, &err);
+ if (err) {
+ monitor_printf(mon, "%s\n", error_get_pretty(err));
+ error_free(err);
+ return;
+ }
+}
+
void hmp_migrate_set_speed(Monitor *mon, const QDict *qdict)
{
int64_t value = qdict_get_int(qdict, "value");
diff --git a/hmp.h b/hmp.h
index f2a890f..0951a0e 100644
--- a/hmp.h
+++ b/hmp.h
@@ -27,6 +27,7 @@ void hmp_info_mice(Monitor *mon);
void hmp_info_migrate(Monitor *mon);
void hmp_info_migration_supported_capabilities(Monitor *mon);
void hmp_info_migrate_capabilities(Monitor *mon);
+void hmp_info_migrate_cache_size(Monitor *mon);
void hmp_info_cpus(Monitor *mon);
void hmp_info_block(Monitor *mon);
void hmp_info_blockstats(Monitor *mon);
@@ -54,6 +55,7 @@ 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_capability(Monitor *mon, const QDict *qdict);
+void hmp_migrate_set_cachesize(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 48a5270..ed9c027 100644
--- a/migration.c
+++ b/migration.c
@@ -518,6 +518,25 @@ void qmp_migrate_cancel(Error **errp)
migrate_fd_cancel(migrate_get_current());
}
+void qmp_migrate_set_cache_size(int64_t value, Error **errp)
+{
+ MigrationState *s = migrate_get_current();
+
+ /* Check for truncation */
+ if (value != (size_t)value) {
+ error_set(errp, QERR_INVALID_PARAMETER_VALUE, "cache size",
+ "exceeding address space");
+ return;
+ }
+
+ s->xbzrle_cache_size = xbzrle_cache_resize(value);
+}
+
+int64_t qmp_query_migrate_cache_size(Error **errp)
+{
+ return migrate_xbzrle_cache_size();
+}
+
void qmp_migrate_set_speed(int64_t value, Error **errp)
{
MigrationState *s;
diff --git a/migration.h b/migration.h
index cdf6787..337e225 100644
--- a/migration.h
+++ b/migration.h
@@ -108,4 +108,6 @@ int xbzrle_decode_buffer(uint8_t *src, int slen, uint8_t *dst, int dlen);
int migrate_use_xbzrle(void);
int64_t migrate_xbzrle_cache_size(void);
+int64_t xbzrle_cache_resize(int64_t new_size);
+
#endif
diff --git a/monitor.c b/monitor.c
index 58d6e2a..6f10304 100644
--- a/monitor.c
+++ b/monitor.c
@@ -2676,6 +2676,13 @@ static mon_cmd_t info_cmds[] = {
.mhandler.info = hmp_info_migrate_capabilities,
},
{
+ .name = "migrate-cache-size",
+ .args_type = "",
+ .params = "",
+ .help = "show current migration xbzrle cache size",
+ .mhandler.info = hmp_info_migrate_cache_size,
+ },
+ {
.name = "balloon",
.args_type = "",
.params = "",
diff --git a/qapi-schema.json b/qapi-schema.json
index f38dfc6..819e45f 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -1412,6 +1412,33 @@
{ 'command': 'migrate_set_speed', 'data': {'value': 'int'} }
##
+# @migrate-set-cache-size
+#
+# Set XBZRLE cache size
+#
+# @value: cache size in bytes
+#
+# The size will be rounded down to the nearest power of 2.
+# The cache size can be modified before and during ongoing migration
+#
+# Returns: nothing on success
+#
+# Since: 1.2
+##
+{ 'command': 'migrate-set-cache-size', 'data': {'value': 'int'} }
+
+##
+# @query-migrate-cache-size
+#
+# query XBZRLE cache size
+#
+# Returns: XBZRLE cache size in bytes
+#
+# Since: 1.2
+##
+{ 'command': 'query-migrate-cache-size', 'returns': 'int' }
+
+##
# @ObjectPropertyInfo:
#
# @name: the name of the property
diff --git a/qmp-commands.hx b/qmp-commands.hx
index 0d527e4..679594f 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -520,6 +520,50 @@ Example:
<- { "return": {} }
EQMP
+{
+ .name = "migrate-set-cache-size",
+ .args_type = "value:o",
+ .mhandler.cmd_new = qmp_marshal_input_migrate_set_cache_size,
+ },
+
+SQMP
+migrate-set-cache-size
+---------------------
+
+Set cache size to be used by XBZRLE migration, the cache size will be rounded
+down to the nearest power of 2
+
+Arguments:
+
+- "value": cache size in bytes (json-int)
+
+Example:
+
+-> { "execute": "migrate-set-cache-size", "arguments": { "value": 536870912 } }
+<- { "return": {} }
+
+EQMP
+ {
+ .name = "query-migrate-cache-size",
+ .args_type = "",
+ .mhandler.cmd_new = qmp_marshal_input_query_migrate_cache_size,
+ },
+
+SQMP
+query-migrate-cache-size
+---------------------
+
+Show cache size to be used by XBZRLE migration
+
+returns a json-object with the following information:
+- "size" : json-int
+
+Example:
+
+-> { "execute": "query-migrate-cache-size" }
+<- { "return": { "size" : "123456" } }
+
+EQMP
{
.name = "migrate_set_speed",
--
1.7.7.6
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [Qemu-devel] [PATCH 09/11] Add migration accounting for normal and duplicate pages
2012-07-31 18:54 [Qemu-devel] [PATCH 00/11] Migration next v8 Orit Wasserman
` (7 preceding siblings ...)
2012-07-31 18:54 ` [Qemu-devel] [PATCH 08/11] Add migrate_set_cachesize command Orit Wasserman
@ 2012-07-31 18:54 ` Orit Wasserman
2012-07-31 18:54 ` [Qemu-devel] [PATCH 10/11] Add XBZRLE statistics Orit Wasserman
2012-07-31 18:54 ` [Qemu-devel] [PATCH 11/11] Restart optimization on stage3 update version Orit Wasserman
10 siblings, 0 replies; 32+ messages in thread
From: Orit Wasserman @ 2012-07-31 18:54 UTC (permalink / raw)
To: qemu-devel
Cc: peter.maydell, aliguori, quintela, Petter Svard, stefanha, mdroth,
Benoit Hudzia, lcapitulino, blauwirbel, Orit Wasserman,
chegu_vinod, avi, Aidan Shribman, pbonzini, eblake
Signed-off-by: Benoit Hudzia <benoit.hudzia@sap.com>
Signed-off-by: Petter Svard <petters@cs.umu.se>
Signed-off-by: Aidan Shribman <aidan.shribman@sap.com>
Signed-off-by: Orit Wasserman <owasserm@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
---
arch_init.c | 38 ++++++++++++++++++++++++++++++++++++++
hmp.c | 6 ++++++
migration.c | 6 ++++++
migration.h | 5 +++++
qapi-schema.json | 11 +++++++++--
qmp-commands.hx | 18 +++++++++++++++---
6 files changed, 79 insertions(+), 5 deletions(-)
diff --git a/arch_init.c b/arch_init.c
index d709ccb..7f12317 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -199,6 +199,40 @@ int64_t xbzrle_cache_resize(int64_t new_size)
return pow2floor(new_size);
}
+/* accounting for migration statistics */
+typedef struct AccountingInfo {
+ uint64_t dup_pages;
+ uint64_t norm_pages;
+ uint64_t iterations;
+} AccountingInfo;
+
+static AccountingInfo acct_info;
+
+static void acct_clear(void)
+{
+ memset(&acct_info, 0, sizeof(acct_info));
+}
+
+uint64_t dup_mig_bytes_transferred(void)
+{
+ return acct_info.dup_pages * TARGET_PAGE_SIZE;
+}
+
+uint64_t dup_mig_pages_transferred(void)
+{
+ return acct_info.dup_pages;
+}
+
+uint64_t norm_mig_bytes_transferred(void)
+{
+ return acct_info.norm_pages * TARGET_PAGE_SIZE;
+}
+
+uint64_t norm_mig_pages_transferred(void)
+{
+ return acct_info.norm_pages;
+}
+
static void save_block_hdr(QEMUFile *f, RAMBlock *block, ram_addr_t offset,
int cont, int flag)
{
@@ -293,6 +327,7 @@ static int ram_save_block(QEMUFile *f)
p = memory_region_get_ram_ptr(mr) + offset;
if (is_dup_page(p)) {
+ acct_info.dup_pages++;
save_block_hdr(f, block, offset, cont, RAM_SAVE_FLAG_COMPRESS);
qemu_put_byte(f, *p);
bytes_sent = 1;
@@ -308,6 +343,7 @@ static int ram_save_block(QEMUFile *f)
save_block_hdr(f, block, offset, cont, RAM_SAVE_FLAG_PAGE);
qemu_put_buffer(f, p, TARGET_PAGE_SIZE);
bytes_sent = TARGET_PAGE_SIZE;
+ acct_info.norm_pages++;
}
/* if page is unmodified, continue to the next */
@@ -429,6 +465,7 @@ static int ram_save_setup(QEMUFile *f, void *opaque)
}
XBZRLE.encoded_buf = g_malloc0(TARGET_PAGE_SIZE);
XBZRLE.current_buf = g_malloc(TARGET_PAGE_SIZE);
+ acct_clear();
}
/* Make sure all dirty bits are set */
@@ -477,6 +514,7 @@ static int ram_save_iterate(QEMUFile *f, void *opaque)
break;
}
bytes_transferred += bytes_sent;
+ acct_info.iterations++;
/* we want to check in the 1st loop, just in case it was the 1st time
and we had to sync the dirty bitmap.
qemu_get_clock_ns() is a bit expensive, so we only check each some
diff --git a/hmp.c b/hmp.c
index 3a61da5..f19a63b 100644
--- a/hmp.c
+++ b/hmp.c
@@ -160,6 +160,12 @@ void hmp_info_migrate(Monitor *mon)
info->ram->total >> 10);
monitor_printf(mon, "total time: %" PRIu64 " milliseconds\n",
info->ram->total_time);
+ monitor_printf(mon, "duplicate: %" PRIu64 " pages\n",
+ info->ram->duplicate);
+ monitor_printf(mon, "normal: %" PRIu64 " pagess\n",
+ info->ram->normal);
+ monitor_printf(mon, "normal bytes: %" PRIu64 " kbytes\n",
+ info->ram->normal_bytes >> 10);
}
if (info->has_disk) {
diff --git a/migration.c b/migration.c
index ed9c027..9e3b17a 100644
--- a/migration.c
+++ b/migration.c
@@ -156,6 +156,9 @@ MigrationInfo *qmp_query_migrate(Error **errp)
info->ram->total = ram_bytes_total();
info->ram->total_time = qemu_get_clock_ms(rt_clock)
- s->total_time;
+ info->ram->duplicate = dup_mig_pages_transferred();
+ info->ram->normal = norm_mig_pages_transferred();
+ info->ram->normal_bytes = norm_mig_bytes_transferred();
if (blk_mig_active()) {
info->has_disk = true;
@@ -175,6 +178,9 @@ MigrationInfo *qmp_query_migrate(Error **errp)
info->ram->remaining = 0;
info->ram->total = ram_bytes_total();
info->ram->total_time = s->total_time;
+ info->ram->duplicate = dup_mig_pages_transferred();
+ info->ram->normal = norm_mig_pages_transferred();
+ info->ram->normal_bytes = norm_mig_bytes_transferred();
break;
case MIG_STATE_ERROR:
info->has_status = true;
diff --git a/migration.h b/migration.h
index 337e225..e4a7cd7 100644
--- a/migration.h
+++ b/migration.h
@@ -87,6 +87,11 @@ uint64_t ram_bytes_total(void);
extern SaveVMHandlers savevm_ram_handlers;
+uint64_t dup_mig_bytes_transferred(void);
+uint64_t dup_mig_pages_transferred(void);
+uint64_t norm_mig_bytes_transferred(void);
+uint64_t norm_mig_pages_transferred(void);
+
/**
* @migrate_add_blocker - prevent migration from proceeding
*
diff --git a/qapi-schema.json b/qapi-schema.json
index 819e45f..e0832ea 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -264,11 +264,18 @@
# migration has ended, it returns the total migration
# time. (since 1.2)
#
-# Since: 0.14.0.
+# @duplicate: number of duplicate pages (since 1.2)
+#
+# @normal : number of normal pages (since 1.2)
+#
+# @normal-bytes : number of normal bytes sent (since 1.2)
+#
+# Since: 0.14.0
##
{ 'type': 'MigrationStats',
'data': {'transferred': 'int', 'remaining': 'int', 'total': 'int' ,
- 'total_time': 'int' } }
+ 'total_time': 'int', 'duplicate': 'int', 'normal': 'int',
+ 'normal-bytes': 'int' } }
##
# @MigrationInfo
diff --git a/qmp-commands.hx b/qmp-commands.hx
index 679594f..f1bbbda 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -2120,6 +2120,9 @@ The main json-object contains the following:
- "transferred": amount transferred (json-int)
- "remaining": amount remaining (json-int)
- "total": total (json-int)
+ - "duplicate": number of duplicated pages (json-int)
+ - "normal" : number of normal pages transferred (json-int)
+ - "normal-bytes" : number of normal bytes transferred (json-int)
- "disk": only present if "status" is "active" and it is a block migration,
it is a json-object with the following disk information (in bytes):
- "transferred": amount transferred (json-int)
@@ -2140,7 +2143,10 @@ Examples:
"ram":{
"transferred":123,
"remaining":123,
- "total":246
+ "total":246,
+ "duplicate":123,
+ "normal":123,
+ "normal-bytes":123456
}
}
}
@@ -2159,7 +2165,10 @@ Examples:
"ram":{
"transferred":123,
"remaining":123,
- "total":246
+ "total":246,
+ "duplicate":123,
+ "normal":123,
+ "normal-bytes":123456
}
}
}
@@ -2173,7 +2182,10 @@ Examples:
"ram":{
"total":1057024,
"remaining":1053304,
- "transferred":3720
+ "transferred":3720,
+ "duplicate":123,
+ "normal":123,
+ "normal-bytes":123456
},
"disk":{
"total":20971520,
--
1.7.7.6
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [Qemu-devel] [PATCH 10/11] Add XBZRLE statistics
2012-07-31 18:54 [Qemu-devel] [PATCH 00/11] Migration next v8 Orit Wasserman
` (8 preceding siblings ...)
2012-07-31 18:54 ` [Qemu-devel] [PATCH 09/11] Add migration accounting for normal and duplicate pages Orit Wasserman
@ 2012-07-31 18:54 ` Orit Wasserman
2012-07-31 18:54 ` [Qemu-devel] [PATCH 11/11] Restart optimization on stage3 update version Orit Wasserman
10 siblings, 0 replies; 32+ messages in thread
From: Orit Wasserman @ 2012-07-31 18:54 UTC (permalink / raw)
To: qemu-devel
Cc: peter.maydell, aliguori, quintela, Petter Svard, stefanha, mdroth,
Benoit Hudzia, lcapitulino, blauwirbel, Orit Wasserman,
chegu_vinod, avi, Aidan Shribman, pbonzini, eblake
Signed-off-by: Benoit Hudzia <benoit.hudzia@sap.com>
Signed-off-by: Petter Svard <petters@cs.umu.se>
Signed-off-by: Aidan Shribman <aidan.shribman@sap.com>
Signed-off-by: Orit Wasserman <owasserm@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
---
arch_init.c | 28 ++++++++++++++++++++++++++++
hmp.c | 13 +++++++++++++
migration.c | 17 +++++++++++++++++
migration.h | 4 ++++
qapi-schema.json | 28 +++++++++++++++++++++++++++-
qmp-commands.hx | 35 +++++++++++++++++++++++++++++++++++
6 files changed, 124 insertions(+), 1 deletions(-)
diff --git a/arch_init.c b/arch_init.c
index 7f12317..9833d54 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -203,7 +203,11 @@ int64_t xbzrle_cache_resize(int64_t new_size)
typedef struct AccountingInfo {
uint64_t dup_pages;
uint64_t norm_pages;
+ uint64_t xbzrle_bytes;
+ uint64_t xbzrle_pages;
+ uint64_t xbzrle_cache_miss;
uint64_t iterations;
+ uint64_t xbzrle_overflows;
} AccountingInfo;
static AccountingInfo acct_info;
@@ -233,6 +237,26 @@ uint64_t norm_mig_pages_transferred(void)
return acct_info.norm_pages;
}
+uint64_t xbzrle_mig_bytes_transferred(void)
+{
+ return acct_info.xbzrle_bytes;
+}
+
+uint64_t xbzrle_mig_pages_transferred(void)
+{
+ return acct_info.xbzrle_pages;
+}
+
+uint64_t xbzrle_mig_pages_cache_miss(void)
+{
+ return acct_info.xbzrle_cache_miss;
+}
+
+uint64_t xbzrle_mig_pages_overflow(void)
+{
+ return acct_info.xbzrle_overflows;
+}
+
static void save_block_hdr(QEMUFile *f, RAMBlock *block, ram_addr_t offset,
int cont, int flag)
{
@@ -257,6 +281,7 @@ static int save_xbzrle_page(QEMUFile *f, uint8_t *current_data,
if (!cache_is_cached(XBZRLE.cache, current_addr)) {
cache_insert(XBZRLE.cache, current_addr,
g_memdup(current_data, TARGET_PAGE_SIZE));
+ acct_info.xbzrle_cache_miss++;
return -1;
}
@@ -274,6 +299,7 @@ static int save_xbzrle_page(QEMUFile *f, uint8_t *current_data,
return 0;
} else if (encoded_len == -1) {
DPRINTF("Overflow\n");
+ acct_info.xbzrle_overflows++;
/* update data in the cache */
memcpy(prev_cached_page, current_data, TARGET_PAGE_SIZE);
return -1;
@@ -288,6 +314,8 @@ static int save_xbzrle_page(QEMUFile *f, uint8_t *current_data,
qemu_put_be16(f, encoded_len);
qemu_put_buffer(f, XBZRLE.encoded_buf, encoded_len);
bytes_sent = encoded_len + 1 + 2;
+ acct_info.xbzrle_pages++;
+ acct_info.xbzrle_bytes += bytes_sent;
return bytes_sent;
}
diff --git a/hmp.c b/hmp.c
index f19a63b..a05145a 100644
--- a/hmp.c
+++ b/hmp.c
@@ -177,6 +177,19 @@ void hmp_info_migrate(Monitor *mon)
info->disk->total >> 10);
}
+ if (info->has_xbzrle_cache) {
+ monitor_printf(mon, "cache size: %" PRIu64 " bytes\n",
+ info->xbzrle_cache->cache_size);
+ monitor_printf(mon, "xbzrle transferred: %" PRIu64 " kbytes\n",
+ info->xbzrle_cache->xbzrle_bytes >> 10);
+ monitor_printf(mon, "xbzrle pages: %" PRIu64 " pages\n",
+ info->xbzrle_cache->xbzrle_pages);
+ monitor_printf(mon, "xbzrle cache miss: %" PRIu64 "\n",
+ info->xbzrle_cache->xbzrle_cache_miss);
+ monitor_printf(mon, "xbzrle overflow : %" PRIu64 "\n",
+ info->xbzrle_cache->xbzrle_overflow);
+ }
+
qapi_free_MigrationInfo(info);
qapi_free_MigrationCapabilityStatusList(caps);
}
diff --git a/migration.c b/migration.c
index 9e3b17a..a506bbb 100644
--- a/migration.c
+++ b/migration.c
@@ -136,6 +136,19 @@ MigrationCapabilityStatusList *qmp_query_migrate_capabilities(Error **errp)
return caps;
}
+static void get_xbzrle_cache_stats(MigrationInfo *info)
+{
+ if (migrate_use_xbzrle()) {
+ info->has_xbzrle_cache = true;
+ info->xbzrle_cache = g_malloc0(sizeof(*info->xbzrle_cache));
+ info->xbzrle_cache->cache_size = migrate_xbzrle_cache_size();
+ info->xbzrle_cache->xbzrle_bytes = xbzrle_mig_bytes_transferred();
+ info->xbzrle_cache->xbzrle_pages = xbzrle_mig_pages_transferred();
+ info->xbzrle_cache->xbzrle_cache_miss = xbzrle_mig_pages_cache_miss();
+ info->xbzrle_cache->xbzrle_overflow = xbzrle_mig_pages_overflow();
+ }
+}
+
MigrationInfo *qmp_query_migrate(Error **errp)
{
MigrationInfo *info = g_malloc0(sizeof(*info));
@@ -167,8 +180,12 @@ MigrationInfo *qmp_query_migrate(Error **errp)
info->disk->remaining = blk_mig_bytes_remaining();
info->disk->total = blk_mig_bytes_total();
}
+
+ get_xbzrle_cache_stats(info);
break;
case MIG_STATE_COMPLETED:
+ get_xbzrle_cache_stats(info);
+
info->has_status = true;
info->status = g_strdup("completed");
diff --git a/migration.h b/migration.h
index e4a7cd7..a9852fc 100644
--- a/migration.h
+++ b/migration.h
@@ -91,6 +91,10 @@ uint64_t dup_mig_bytes_transferred(void);
uint64_t dup_mig_pages_transferred(void);
uint64_t norm_mig_bytes_transferred(void);
uint64_t norm_mig_pages_transferred(void);
+uint64_t xbzrle_mig_bytes_transferred(void);
+uint64_t xbzrle_mig_pages_transferred(void);
+uint64_t xbzrle_mig_pages_overflow(void);
+uint64_t xbzrle_mig_pages_cache_miss(void);
/**
* @migrate_add_blocker - prevent migration from proceeding
diff --git a/qapi-schema.json b/qapi-schema.json
index e0832ea..e7cfb78 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -278,6 +278,27 @@
'normal-bytes': 'int' } }
##
+# @XBZRLECacheStats
+#
+# Detailed XBZRLE migration cache statistics
+#
+# @cache-size: XBZRLE cache size
+#
+# @xbzrle-bytes: amount of bytes already transferred to the target VM
+#
+# @xbzrle-pages: amount of pages transferred to the target VM
+#
+# @xbzrle-cache-miss: @optional, number of cache miss
+#
+# @xbzrle-overflow: number of overflows
+#
+# Since: 1.2
+##
+{ 'type': 'XBZRLECacheStats',
+ 'data': {'cache-size': 'int', 'xbzrle-bytes': 'int', 'xbzrle-pages': 'int',
+ 'xbzrle-cache-miss': 'int', 'xbzrle-overflow': 'int' } }
+
+##
# @MigrationInfo
#
# Information about current migration process.
@@ -295,11 +316,16 @@
# status, only returned if status is 'active' and it is a block
# migration
#
+# @xbzrle-cache: #optional @XBZRLECacheStats containing detailed XBZRLE
+# migration statistics, only returned if XBZRLE feature is on and
+# status is 'active' or 'completed' (since 1.2)
+#
# Since: 0.14.0
##
{ 'type': 'MigrationInfo',
'data': {'*status': 'str', '*ram': 'MigrationStats',
- '*disk': 'MigrationStats'} }
+ '*disk': 'MigrationStats',
+ '*xbzrle-cache': 'XBZRLECacheStats'} }
##
# @query-migrate
diff --git a/qmp-commands.hx b/qmp-commands.hx
index f1bbbda..a5b35b0 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -2128,6 +2128,17 @@ The main json-object contains the following:
- "transferred": amount transferred (json-int)
- "remaining": amount remaining (json-int)
- "total": total (json-int)
+- "xbzrle-cache": only present if XBZRLE is active.
+ It is a json-object with the following XBZRLE information:
+ - "cache-size": XBZRLE cache size
+ - "xbzrle-bytes": total XBZRLE bytes transferred, only present if
+ status is "active" or "completed"
+ - "xbzrle-pages": number of XBZRLE compressed pages, only present if
+ status is "active" or "completed"
+ - "cache-miss": number of cache misses, only present if
+ status is "active" or "completed"
+ - "overflow": number of XBZRLE overflows, only present if
+ status is "active" or "completed"
Examples:
1. Before the first migration
@@ -2195,6 +2206,30 @@ Examples:
}
}
+6. Migration is being performed and XBZRLE is active:
+
+-> { "execute": "query-migrate" }
+<- {
+ "return":{
+ "status":"active",
+ "capabilities" : [ { "capability": "xbzrle", "state" : true } ],
+ "ram":{
+ "total":1057024,
+ "remaining":1053304,
+ "transferred":3720,
+ "duplicate": 10,
+ "normal" : 3333
+ },
+ "cache":{
+ "cache-size": 1024
+ "xbzrle-transferred":20971520,
+ "xbzrle-pages":2444343,
+ "xbzrle-cache-miss":2244,
+ "xbzrle-overflow":34434
+ }
+ }
+ }
+
EQMP
{
--
1.7.7.6
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [Qemu-devel] [PATCH 11/11] Restart optimization on stage3 update version
2012-07-31 18:54 [Qemu-devel] [PATCH 00/11] Migration next v8 Orit Wasserman
` (9 preceding siblings ...)
2012-07-31 18:54 ` [Qemu-devel] [PATCH 10/11] Add XBZRLE statistics Orit Wasserman
@ 2012-07-31 18:54 ` Orit Wasserman
10 siblings, 0 replies; 32+ messages in thread
From: Orit Wasserman @ 2012-07-31 18:54 UTC (permalink / raw)
To: qemu-devel
Cc: peter.maydell, aliguori, quintela, stefanha, mdroth, lcapitulino,
blauwirbel, chegu_vinod, avi, pbonzini, eblake
From: Juan Quintela <quintela@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
---
arch_init.c | 24 +++++++++++++++---------
1 files changed, 15 insertions(+), 9 deletions(-)
diff --git a/arch_init.c b/arch_init.c
index 9833d54..21031d1 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -273,14 +273,16 @@ static void save_block_hdr(QEMUFile *f, RAMBlock *block, ram_addr_t offset,
static int save_xbzrle_page(QEMUFile *f, uint8_t *current_data,
ram_addr_t current_addr, RAMBlock *block,
- ram_addr_t offset, int cont)
+ ram_addr_t offset, int cont, bool last_stage)
{
int encoded_len = 0, bytes_sent = -1;
uint8_t *prev_cached_page;
if (!cache_is_cached(XBZRLE.cache, current_addr)) {
- cache_insert(XBZRLE.cache, current_addr,
- g_memdup(current_data, TARGET_PAGE_SIZE));
+ if (!last_stage) {
+ cache_insert(XBZRLE.cache, current_addr,
+ g_memdup(current_data, TARGET_PAGE_SIZE));
+ }
acct_info.xbzrle_cache_miss++;
return -1;
}
@@ -306,7 +308,9 @@ static int save_xbzrle_page(QEMUFile *f, uint8_t *current_data,
}
/* we need to update the data in the cache, in order to get the same data */
- memcpy(prev_cached_page, XBZRLE.current_buf, TARGET_PAGE_SIZE);
+ if (!last_stage) {
+ memcpy(prev_cached_page, XBZRLE.current_buf, TARGET_PAGE_SIZE);
+ }
/* Send XBZRLE based compressed page */
save_block_hdr(f, block, offset, cont, RAM_SAVE_FLAG_XBZRLE);
@@ -331,7 +335,7 @@ static ram_addr_t last_offset;
* n: the amount of bytes written in other case
*/
-static int ram_save_block(QEMUFile *f)
+static int ram_save_block(QEMUFile *f, bool last_stage)
{
RAMBlock *block = last_block;
ram_addr_t offset = last_offset;
@@ -362,8 +366,10 @@ static int ram_save_block(QEMUFile *f)
} else if (migrate_use_xbzrle()) {
current_addr = block->offset + offset;
bytes_sent = save_xbzrle_page(f, p, current_addr, block,
- offset, cont);
- p = get_cached_data(XBZRLE.cache, current_addr);
+ offset, cont, last_stage);
+ if (!last_stage) {
+ p = get_cached_data(XBZRLE.cache, current_addr);
+ }
}
/* either we didn't send yet (we may have had XBZRLE overflow) */
@@ -536,7 +542,7 @@ static int ram_save_iterate(QEMUFile *f, void *opaque)
while ((ret = qemu_file_rate_limit(f)) == 0) {
int bytes_sent;
- bytes_sent = ram_save_block(f);
+ bytes_sent = ram_save_block(f, false);
/* no more blocks to sent */
if (bytes_sent < 0) {
break;
@@ -598,7 +604,7 @@ static int ram_save_complete(QEMUFile *f, void *opaque)
while (true) {
int bytes_sent;
- bytes_sent = ram_save_block(f);
+ bytes_sent = ram_save_block(f, true);
/* no more blocks to sent */
if (bytes_sent < 0) {
break;
--
1.7.7.6
^ permalink raw reply related [flat|nested] 32+ messages in thread
* Re: [Qemu-devel] [PATCH 02/11] Add migrate_set_parameter and query-migrate-parameters
2012-07-31 18:54 ` [Qemu-devel] [PATCH 02/11] Add migrate_set_parameter and query-migrate-parameters Orit Wasserman
@ 2012-07-31 19:29 ` Eric Blake
2012-07-31 20:05 ` [Qemu-devel] [PATCH 02/11] Add migrate_set_capabilities and query-migrate-capabilities Orit Wasserman
1 sibling, 0 replies; 32+ messages in thread
From: Eric Blake @ 2012-07-31 19:29 UTC (permalink / raw)
To: Orit Wasserman
Cc: peter.maydell, aliguori, quintela, stefanha, qemu-devel, mdroth,
blauwirbel, avi, pbonzini, lcapitulino, chegu_vinod
[-- Attachment #1: Type: text/plain, Size: 1652 bytes --]
On 07/31/2012 12:54 PM, Orit Wasserman wrote:
Subject line is stale.
> The management can enable/disable a capability for the next migration by using
> migrate_set_capabilities QMP command.
The QMP command is spelled migrate-set-capabilities.
> The management can query the current migration capabilities using
> query-migrate-capabilities QMP command.
> The user can use migrate_set_capability and 'info migrate_capabilities' HMP
> commands.
>
> Signed-off-by: Orit Wasserman <owasserm@redhat.com>
> Signed-off-by: Juan Quintela <quintela@redhat.com>
> ---
> +++ b/qmp-commands.hx
> @@ -2081,7 +2081,6 @@ The main json-object contains the following:
> - "transferred": amount transferred (json-int)
> - "remaining": amount remaining (json-int)
> - "total": total (json-int)
> -
> Examples:
Spurious whitespace change.
>
> 1. Before the first migration
> @@ -2092,7 +2091,15 @@ Examples:
> 2. Migration is done and has succeeded
>
> -> { "execute": "query-migrate" }
> -<- { "return": { "status": "completed" } }
> +<- { "return": {
> + "status": "completed",
> + "ram":{
> + "transferred":123,
> + "remaining":123,
> + "total":246
> + }
> + }
> + }
This hunk is unrelated to the new commands, and not mentioned in the
commit message. It's a good change (making the examples match the
code), but belongs better in a separate cleanup commit that scrubs
existing docs before adding new docs.
--
Eric Blake eblake@redhat.com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 620 bytes --]
^ permalink raw reply [flat|nested] 32+ messages in thread
* [Qemu-devel] [PATCH 02/11] Add migrate_set_capabilities and query-migrate-capabilities
2012-07-31 18:54 ` [Qemu-devel] [PATCH 02/11] Add migrate_set_parameter and query-migrate-parameters Orit Wasserman
2012-07-31 19:29 ` Eric Blake
@ 2012-07-31 20:05 ` Orit Wasserman
2012-08-01 7:05 ` Orit Wasserman
2012-08-01 7:08 ` [Qemu-devel] [PATCH 02/11] Add migrate-set-capabilities " Orit Wasserman
1 sibling, 2 replies; 32+ messages in thread
From: Orit Wasserman @ 2012-07-31 20:05 UTC (permalink / raw)
To: qemu-devel
Cc: peter.maydell, aliguori, quintela, stefanha, mdroth, lcapitulino,
blauwirbel, Orit Wasserman, chegu_vinod, avi, pbonzini, eblake
The management can enable/disable a capability for the next migration by using
migrate-set-apabilities QMP command.
The management can query the current migration capabilities using
query-migrate-capabilities QMP command.
The user can use migrate_set_capability and 'info migrate_capabilities' HMP
commands.
Signed-off-by: Orit Wasserman <owasserm@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
---
hmp-commands.hx | 16 +++++++++++++
hmp.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
hmp.h | 2 +
migration.c | 41 ++++++++++++++++++++++++++++++++++
migration.h | 2 +
monitor.c | 7 +++++
qapi-schema.json | 32 ++++++++++++++++++++++++++
qmp-commands.hx | 49 ++++++++++++++++++++++++++++++++++++++++
8 files changed, 214 insertions(+), 0 deletions(-)
diff --git a/hmp-commands.hx b/hmp-commands.hx
index 8267237..f4c8495 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_capability",
+ .args_type = "capability:s,state:b",
+ .params = "capability state",
+ .help = "Enable/Disable the usage of a capability for migration",
+ .mhandler.cmd = hmp_migrate_set_capability,
+ },
+
+STEXI
+@item migrate_set_capability @var{capability} @var{state}
+@findex migrate_set_capability
+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 user network stack connection states
show migration status
@item info migration_supported_capabilities
show migration supported capabilities
+@item info migrate_capabilities
+show current migration capabilities
@item info balloon
show balloon information
@item info qtree
diff --git a/hmp.c b/hmp.c
index 2ff71a3..463b730 100644
--- a/hmp.c
+++ b/hmp.c
@@ -131,8 +131,21 @@ void hmp_info_mice(Monitor *mon)
void hmp_info_migrate(Monitor *mon)
{
MigrationInfo *info;
+ MigrationCapabilityStatusList *caps, *cap;
info = qmp_query_migrate(NULL);
+ caps = qmp_query_migrate_capabilities(NULL);
+
+ /* do not display parameters during setup */
+ if (info->has_status && caps) {
+ monitor_printf(mon, "capabilities: ");
+ for (cap = caps; 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 +172,7 @@ void hmp_info_migrate(Monitor *mon)
}
qapi_free_MigrationInfo(info);
+ qapi_free_MigrationCapabilityStatusList(caps);
}
void hmp_info_migration_supported_capabilities(Monitor *mon)
@@ -182,6 +196,25 @@ void hmp_info_migration_supported_capabilities(Monitor *mon)
qapi_free_MigrationCapabilityStatusList(caps_list);
}
+void hmp_info_migrate_capabilities(Monitor *mon)
+{
+ MigrationCapabilityStatusList *caps, *cap;
+
+ caps = qmp_query_migrate_capabilities(NULL);
+
+ if (caps) {
+ monitor_printf(mon, "capabilities: ");
+ for (cap = caps; cap; cap = cap->next) {
+ monitor_printf(mon, "%s: %s ",
+ MigrationCapability_lookup[cap->value->capability],
+ cap->value->state ? "on" : "off");
+ }
+ monitor_printf(mon, "\n");
+ }
+
+ qapi_free_MigrationCapabilityStatusList(caps);
+}
+
void hmp_info_cpus(Monitor *mon)
{
CpuInfoList *cpu_list, *cpu;
@@ -756,6 +789,38 @@ void hmp_migrate_set_speed(Monitor *mon, const QDict *qdict)
qmp_migrate_set_speed(value, NULL);
}
+void hmp_migrate_set_capability(Monitor *mon, const QDict *qdict)
+{
+ const char *cap = qdict_get_str(qdict, "capability");
+ bool state = qdict_get_bool(qdict, "state");
+ Error *err = NULL;
+ MigrationCapabilityStatusList *caps = g_malloc0(sizeof(*caps));
+ int i;
+
+ for (i = 0; i < MIGRATION_CAPABILITY_MAX; i++) {
+ if (strcmp(cap, MigrationCapability_lookup[i]) == 0) {
+ caps->value = g_malloc0(sizeof(*caps->value));
+ caps->value->capability = i;
+ caps->value->state = state;
+ caps->next = NULL;
+ qmp_migrate_set_capabilities(caps, &err);
+ break;
+ }
+ }
+
+ if (i == MIGRATION_CAPABILITY_MAX) {
+ error_set(&err, QERR_INVALID_PARAMETER, cap);
+ }
+
+ qapi_free_MigrationCapabilityStatusList(caps);
+
+ 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 8442c22..f2a890f 100644
--- a/hmp.h
+++ b/hmp.h
@@ -26,6 +26,7 @@ void hmp_info_chardev(Monitor *mon);
void hmp_info_mice(Monitor *mon);
void hmp_info_migrate(Monitor *mon);
void hmp_info_migration_supported_capabilities(Monitor *mon);
+void hmp_info_migrate_capabilities(Monitor *mon);
void hmp_info_cpus(Monitor *mon);
void hmp_info_block(Monitor *mon);
void hmp_info_blockstats(Monitor *mon);
@@ -52,6 +53,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_capability(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 35444f7..4b52f36 100644
--- a/migration.c
+++ b/migration.c
@@ -113,6 +113,25 @@ uint64_t migrate_max_downtime(void)
return max_downtime;
}
+MigrationCapabilityStatusList *qmp_query_migrate_capabilities(Error **errp)
+{
+ MigrationCapabilityStatusList *caps = g_malloc0(sizeof(*caps));
+ MigrationCapabilityStatusList *next = NULL;
+ MigrationState *s = migrate_get_current();
+ int i;
+
+ for (i = 0; i < MIGRATION_CAPABILITY_MAX; i++) {
+ caps->value =
+ g_malloc(sizeof(*caps->value));
+ caps->value->capability = i;
+ caps->value->state = s->enabled_capabilities[i];
+ caps->next = next;
+ next = caps;
+ }
+
+ return caps;
+}
+
MigrationInfo *qmp_query_migrate(Error **errp)
{
MigrationInfo *info = g_malloc0(sizeof(*info));
@@ -178,6 +197,22 @@ qmp_query_migration_supported_capabilities(Error **errp)
return caps_list;
}
+void qmp_migrate_set_capabilities(MigrationCapabilityStatusList *params,
+ Error **errp)
+{
+ MigrationState *s = migrate_get_current();
+ MigrationCapabilityStatusList *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)
@@ -387,10 +422,16 @@ 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;
diff --git a/migration.h b/migration.h
index 57572a6..713aae0 100644
--- a/migration.h
+++ b/migration.h
@@ -19,6 +19,7 @@
#include "notify.h"
#include "error.h"
#include "vmstate.h"
+#include "qapi-types.h"
struct MigrationParams {
bool blk;
@@ -39,6 +40,7 @@ struct MigrationState
void *opaque;
MigrationParams params;
int64_t total_time;
+ bool enabled_capabilities[MIGRATION_CAPABILITY_MAX];
};
void process_incoming_migration(QEMUFile *f);
diff --git a/monitor.c b/monitor.c
index 43f7df5..58d6e2a 100644
--- a/monitor.c
+++ b/monitor.c
@@ -2669,6 +2669,13 @@ static mon_cmd_t info_cmds[] = {
.mhandler.info = hmp_info_migration_supported_capabilities,
},
{
+ .name = "migrate_capabilities",
+ .args_type = "",
+ .params = "",
+ .help = "show current migration capabilities",
+ .mhandler.info = hmp_info_migrate_capabilities,
+ },
+ {
.name = "balloon",
.args_type = "",
.params = "",
diff --git a/qapi-schema.json b/qapi-schema.json
index 68d0fbb..f38dfc6 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -345,6 +345,38 @@
{ 'command': 'query-migration-supported-capabilities', 'returns': ['MigrationCapabilityStatus'] }
##
+# @migrate-set-capabilities
+#
+# Enable/Disable the following migration capabilities (like xbzrle)
+#
+# Since: 1.2
+##
+{ 'command': 'migrate-set-capabilities',
+ 'data': { 'capabilities': ['MigrationCapabilityStatus'] } }
+
+##
+# @MigrationParameters
+#
+# @capabilities: @MigrationCapabilityStatus list contain current migration
+# capabilities status
+# Since: 1.2
+##
+{ 'type': 'MigrationParameters',
+ 'data': {'capabilities': ['MigrationCapabilityStatus']} }
+
+
+##
+# @query-migrate-capabilities
+#
+# Returns information about the current migration capabilities status
+#
+# Returns: @MigrationCapabilitiesStatus
+#
+# Since: 1.2
+##
+{ 'command': 'query-migrate-capabilities', 'returns': ['MigrationCapabilityStatus']}
+
+##
# @MouseInfo:
#
# Information about a mouse device.
diff --git a/qmp-commands.hx b/qmp-commands.hx
index 16fbcef..e96a993 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -2166,6 +2166,55 @@ EQMP
},
SQMP
+migrate-set-capabilities
+-------
+
+Enable/Disable migration capabilities
+
+- "xbzrle": xbzrle support
+
+Arguments:
+
+Example:
+
+-> { "execute": "migrate-set-capabilities" , "arguments":
+ { "capabilities": [ { "capability": "xbzrle", "state": true } ] } }
+
+EQMP
+
+ {
+ .name = "migrate_set_capabilities",
+ .args_type = "capabilities:O",
+ .params = "capability:s,state:b",
+ .mhandler.cmd_new = qmp_marshal_input_migrate_set_capabilities,
+ },
+SQMP
+query-migrate-capabilities
+-------
+
+Query current migration capabilities
+
+- "capabilities": migration capabilities state
+ - "xbzrle" : XBZRLE state (json-bool)
+
+Arguments:
+
+Example:
+
+-> { "execute": "query-migrate-capabilities" }
+<- { "return": {
+ "capabilities" : [ { "capability" : "xbzrle", "state" : false } ]
+ }
+ }
+EQMP
+
+ {
+ .name = "query-migrate-capabilities",
+ .args_type = "",
+ .mhandler.cmd_new = qmp_marshal_input_query_migrate_capabilities,
+ },
+
+SQMP
query-balloon
-------------
--
1.7.7.6
^ permalink raw reply related [flat|nested] 32+ messages in thread
* Re: [Qemu-devel] [PATCH 02/11] Add migrate_set_capabilities and query-migrate-capabilities
2012-07-31 20:05 ` [Qemu-devel] [PATCH 02/11] Add migrate_set_capabilities and query-migrate-capabilities Orit Wasserman
@ 2012-08-01 7:05 ` Orit Wasserman
2012-08-01 7:08 ` [Qemu-devel] [PATCH 02/11] Add migrate-set-capabilities " Orit Wasserman
1 sibling, 0 replies; 32+ messages in thread
From: Orit Wasserman @ 2012-08-01 7:05 UTC (permalink / raw)
To: Orit Wasserman
Cc: peter.maydell, aliguori, quintela, stefanha, mdroth, eblake,
qemu-devel, blauwirbel, avi, pbonzini, lcapitulino, chegu_vinod
Still wrong header should be migrate-set-capabilities, I will resend the patch
again.
(note to myself it is better to do stuff in the morning , not late at night :))
Orit
On 07/31/2012 11:05 PM, Orit Wasserman wrote:
> The management can enable/disable a capability for the next migration by using
> migrate-set-apabilities QMP command.
> The management can query the current migration capabilities using
> query-migrate-capabilities QMP command.
> The user can use migrate_set_capability and 'info migrate_capabilities' HMP
> commands.
>
> Signed-off-by: Orit Wasserman <owasserm@redhat.com>
> Signed-off-by: Juan Quintela <quintela@redhat.com>
> ---
> hmp-commands.hx | 16 +++++++++++++
> hmp.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
> hmp.h | 2 +
> migration.c | 41 ++++++++++++++++++++++++++++++++++
> migration.h | 2 +
> monitor.c | 7 +++++
> qapi-schema.json | 32 ++++++++++++++++++++++++++
> qmp-commands.hx | 49 ++++++++++++++++++++++++++++++++++++++++
> 8 files changed, 214 insertions(+), 0 deletions(-)
>
> diff --git a/hmp-commands.hx b/hmp-commands.hx
> index 8267237..f4c8495 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_capability",
> + .args_type = "capability:s,state:b",
> + .params = "capability state",
> + .help = "Enable/Disable the usage of a capability for migration",
> + .mhandler.cmd = hmp_migrate_set_capability,
> + },
> +
> +STEXI
> +@item migrate_set_capability @var{capability} @var{state}
> +@findex migrate_set_capability
> +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 user network stack connection states
> show migration status
> @item info migration_supported_capabilities
> show migration supported capabilities
> +@item info migrate_capabilities
> +show current migration capabilities
> @item info balloon
> show balloon information
> @item info qtree
> diff --git a/hmp.c b/hmp.c
> index 2ff71a3..463b730 100644
> --- a/hmp.c
> +++ b/hmp.c
> @@ -131,8 +131,21 @@ void hmp_info_mice(Monitor *mon)
> void hmp_info_migrate(Monitor *mon)
> {
> MigrationInfo *info;
> + MigrationCapabilityStatusList *caps, *cap;
>
> info = qmp_query_migrate(NULL);
> + caps = qmp_query_migrate_capabilities(NULL);
> +
> + /* do not display parameters during setup */
> + if (info->has_status && caps) {
> + monitor_printf(mon, "capabilities: ");
> + for (cap = caps; 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 +172,7 @@ void hmp_info_migrate(Monitor *mon)
> }
>
> qapi_free_MigrationInfo(info);
> + qapi_free_MigrationCapabilityStatusList(caps);
> }
>
> void hmp_info_migration_supported_capabilities(Monitor *mon)
> @@ -182,6 +196,25 @@ void hmp_info_migration_supported_capabilities(Monitor *mon)
> qapi_free_MigrationCapabilityStatusList(caps_list);
> }
>
> +void hmp_info_migrate_capabilities(Monitor *mon)
> +{
> + MigrationCapabilityStatusList *caps, *cap;
> +
> + caps = qmp_query_migrate_capabilities(NULL);
> +
> + if (caps) {
> + monitor_printf(mon, "capabilities: ");
> + for (cap = caps; cap; cap = cap->next) {
> + monitor_printf(mon, "%s: %s ",
> + MigrationCapability_lookup[cap->value->capability],
> + cap->value->state ? "on" : "off");
> + }
> + monitor_printf(mon, "\n");
> + }
> +
> + qapi_free_MigrationCapabilityStatusList(caps);
> +}
> +
> void hmp_info_cpus(Monitor *mon)
> {
> CpuInfoList *cpu_list, *cpu;
> @@ -756,6 +789,38 @@ void hmp_migrate_set_speed(Monitor *mon, const QDict *qdict)
> qmp_migrate_set_speed(value, NULL);
> }
>
> +void hmp_migrate_set_capability(Monitor *mon, const QDict *qdict)
> +{
> + const char *cap = qdict_get_str(qdict, "capability");
> + bool state = qdict_get_bool(qdict, "state");
> + Error *err = NULL;
> + MigrationCapabilityStatusList *caps = g_malloc0(sizeof(*caps));
> + int i;
> +
> + for (i = 0; i < MIGRATION_CAPABILITY_MAX; i++) {
> + if (strcmp(cap, MigrationCapability_lookup[i]) == 0) {
> + caps->value = g_malloc0(sizeof(*caps->value));
> + caps->value->capability = i;
> + caps->value->state = state;
> + caps->next = NULL;
> + qmp_migrate_set_capabilities(caps, &err);
> + break;
> + }
> + }
> +
> + if (i == MIGRATION_CAPABILITY_MAX) {
> + error_set(&err, QERR_INVALID_PARAMETER, cap);
> + }
> +
> + qapi_free_MigrationCapabilityStatusList(caps);
> +
> + 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 8442c22..f2a890f 100644
> --- a/hmp.h
> +++ b/hmp.h
> @@ -26,6 +26,7 @@ void hmp_info_chardev(Monitor *mon);
> void hmp_info_mice(Monitor *mon);
> void hmp_info_migrate(Monitor *mon);
> void hmp_info_migration_supported_capabilities(Monitor *mon);
> +void hmp_info_migrate_capabilities(Monitor *mon);
> void hmp_info_cpus(Monitor *mon);
> void hmp_info_block(Monitor *mon);
> void hmp_info_blockstats(Monitor *mon);
> @@ -52,6 +53,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_capability(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 35444f7..4b52f36 100644
> --- a/migration.c
> +++ b/migration.c
> @@ -113,6 +113,25 @@ uint64_t migrate_max_downtime(void)
> return max_downtime;
> }
>
> +MigrationCapabilityStatusList *qmp_query_migrate_capabilities(Error **errp)
> +{
> + MigrationCapabilityStatusList *caps = g_malloc0(sizeof(*caps));
> + MigrationCapabilityStatusList *next = NULL;
> + MigrationState *s = migrate_get_current();
> + int i;
> +
> + for (i = 0; i < MIGRATION_CAPABILITY_MAX; i++) {
> + caps->value =
> + g_malloc(sizeof(*caps->value));
> + caps->value->capability = i;
> + caps->value->state = s->enabled_capabilities[i];
> + caps->next = next;
> + next = caps;
> + }
> +
> + return caps;
> +}
> +
> MigrationInfo *qmp_query_migrate(Error **errp)
> {
> MigrationInfo *info = g_malloc0(sizeof(*info));
> @@ -178,6 +197,22 @@ qmp_query_migration_supported_capabilities(Error **errp)
> return caps_list;
> }
>
> +void qmp_migrate_set_capabilities(MigrationCapabilityStatusList *params,
> + Error **errp)
> +{
> + MigrationState *s = migrate_get_current();
> + MigrationCapabilityStatusList *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)
> @@ -387,10 +422,16 @@ 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;
> diff --git a/migration.h b/migration.h
> index 57572a6..713aae0 100644
> --- a/migration.h
> +++ b/migration.h
> @@ -19,6 +19,7 @@
> #include "notify.h"
> #include "error.h"
> #include "vmstate.h"
> +#include "qapi-types.h"
>
> struct MigrationParams {
> bool blk;
> @@ -39,6 +40,7 @@ struct MigrationState
> void *opaque;
> MigrationParams params;
> int64_t total_time;
> + bool enabled_capabilities[MIGRATION_CAPABILITY_MAX];
> };
>
> void process_incoming_migration(QEMUFile *f);
> diff --git a/monitor.c b/monitor.c
> index 43f7df5..58d6e2a 100644
> --- a/monitor.c
> +++ b/monitor.c
> @@ -2669,6 +2669,13 @@ static mon_cmd_t info_cmds[] = {
> .mhandler.info = hmp_info_migration_supported_capabilities,
> },
> {
> + .name = "migrate_capabilities",
> + .args_type = "",
> + .params = "",
> + .help = "show current migration capabilities",
> + .mhandler.info = hmp_info_migrate_capabilities,
> + },
> + {
> .name = "balloon",
> .args_type = "",
> .params = "",
> diff --git a/qapi-schema.json b/qapi-schema.json
> index 68d0fbb..f38dfc6 100644
> --- a/qapi-schema.json
> +++ b/qapi-schema.json
> @@ -345,6 +345,38 @@
> { 'command': 'query-migration-supported-capabilities', 'returns': ['MigrationCapabilityStatus'] }
>
> ##
> +# @migrate-set-capabilities
> +#
> +# Enable/Disable the following migration capabilities (like xbzrle)
> +#
> +# Since: 1.2
> +##
> +{ 'command': 'migrate-set-capabilities',
> + 'data': { 'capabilities': ['MigrationCapabilityStatus'] } }
> +
> +##
> +# @MigrationParameters
> +#
> +# @capabilities: @MigrationCapabilityStatus list contain current migration
> +# capabilities status
> +# Since: 1.2
> +##
> +{ 'type': 'MigrationParameters',
> + 'data': {'capabilities': ['MigrationCapabilityStatus']} }
> +
> +
> +##
> +# @query-migrate-capabilities
> +#
> +# Returns information about the current migration capabilities status
> +#
> +# Returns: @MigrationCapabilitiesStatus
> +#
> +# Since: 1.2
> +##
> +{ 'command': 'query-migrate-capabilities', 'returns': ['MigrationCapabilityStatus']}
> +
> +##
> # @MouseInfo:
> #
> # Information about a mouse device.
> diff --git a/qmp-commands.hx b/qmp-commands.hx
> index 16fbcef..e96a993 100644
> --- a/qmp-commands.hx
> +++ b/qmp-commands.hx
> @@ -2166,6 +2166,55 @@ EQMP
> },
>
> SQMP
> +migrate-set-capabilities
> +-------
> +
> +Enable/Disable migration capabilities
> +
> +- "xbzrle": xbzrle support
> +
> +Arguments:
> +
> +Example:
> +
> +-> { "execute": "migrate-set-capabilities" , "arguments":
> + { "capabilities": [ { "capability": "xbzrle", "state": true } ] } }
> +
> +EQMP
> +
> + {
> + .name = "migrate_set_capabilities",
> + .args_type = "capabilities:O",
> + .params = "capability:s,state:b",
> + .mhandler.cmd_new = qmp_marshal_input_migrate_set_capabilities,
> + },
> +SQMP
> +query-migrate-capabilities
> +-------
> +
> +Query current migration capabilities
> +
> +- "capabilities": migration capabilities state
> + - "xbzrle" : XBZRLE state (json-bool)
> +
> +Arguments:
> +
> +Example:
> +
> +-> { "execute": "query-migrate-capabilities" }
> +<- { "return": {
> + "capabilities" : [ { "capability" : "xbzrle", "state" : false } ]
> + }
> + }
> +EQMP
> +
> + {
> + .name = "query-migrate-capabilities",
> + .args_type = "",
> + .mhandler.cmd_new = qmp_marshal_input_query_migrate_capabilities,
> + },
> +
> +SQMP
> query-balloon
> -------------
>
>
^ permalink raw reply [flat|nested] 32+ messages in thread
* [Qemu-devel] [PATCH 02/11] Add migrate-set-capabilities and query-migrate-capabilities
2012-07-31 20:05 ` [Qemu-devel] [PATCH 02/11] Add migrate_set_capabilities and query-migrate-capabilities Orit Wasserman
2012-08-01 7:05 ` Orit Wasserman
@ 2012-08-01 7:08 ` Orit Wasserman
1 sibling, 0 replies; 32+ messages in thread
From: Orit Wasserman @ 2012-08-01 7:08 UTC (permalink / raw)
To: qemu-devel
Cc: peter.maydell, aliguori, quintela, stefanha, mdroth, lcapitulino,
blauwirbel, Orit Wasserman, chegu_vinod, avi, pbonzini, eblake
The management can enable/disable a capability for the next migration by using
migrate-set-apabilities QMP command.
The management can query the current migration capabilities using
query-migrate-capabilities QMP command.
The user can use migrate_set_capability and 'info migrate_capabilities' HMP
commands.
Signed-off-by: Orit Wasserman <owasserm@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
---
hmp-commands.hx | 16 +++++++++++++
hmp.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
hmp.h | 2 +
migration.c | 46 ++++++++++++++++++++++++++++++++++++++
migration.h | 2 +
monitor.c | 7 +++++
qapi-schema.json | 32 ++++++++++++++++++++++++++
qmp-commands.hx | 49 ++++++++++++++++++++++++++++++++++++++++
8 files changed, 219 insertions(+), 0 deletions(-)
diff --git a/hmp-commands.hx b/hmp-commands.hx
index 8267237..f4c8495 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_capability",
+ .args_type = "capability:s,state:b",
+ .params = "capability state",
+ .help = "Enable/Disable the usage of a capability for migration",
+ .mhandler.cmd = hmp_migrate_set_capability,
+ },
+
+STEXI
+@item migrate_set_capability @var{capability} @var{state}
+@findex migrate_set_capability
+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 user network stack connection states
show migration status
@item info migration_supported_capabilities
show migration supported capabilities
+@item info migrate_capabilities
+show current migration capabilities
@item info balloon
show balloon information
@item info qtree
diff --git a/hmp.c b/hmp.c
index 2ff71a3..463b730 100644
--- a/hmp.c
+++ b/hmp.c
@@ -131,8 +131,21 @@ void hmp_info_mice(Monitor *mon)
void hmp_info_migrate(Monitor *mon)
{
MigrationInfo *info;
+ MigrationCapabilityStatusList *caps, *cap;
info = qmp_query_migrate(NULL);
+ caps = qmp_query_migrate_capabilities(NULL);
+
+ /* do not display parameters during setup */
+ if (info->has_status && caps) {
+ monitor_printf(mon, "capabilities: ");
+ for (cap = caps; 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 +172,7 @@ void hmp_info_migrate(Monitor *mon)
}
qapi_free_MigrationInfo(info);
+ qapi_free_MigrationCapabilityStatusList(caps);
}
void hmp_info_migration_supported_capabilities(Monitor *mon)
@@ -182,6 +196,25 @@ void hmp_info_migration_supported_capabilities(Monitor *mon)
qapi_free_MigrationCapabilityStatusList(caps_list);
}
+void hmp_info_migrate_capabilities(Monitor *mon)
+{
+ MigrationCapabilityStatusList *caps, *cap;
+
+ caps = qmp_query_migrate_capabilities(NULL);
+
+ if (caps) {
+ monitor_printf(mon, "capabilities: ");
+ for (cap = caps; cap; cap = cap->next) {
+ monitor_printf(mon, "%s: %s ",
+ MigrationCapability_lookup[cap->value->capability],
+ cap->value->state ? "on" : "off");
+ }
+ monitor_printf(mon, "\n");
+ }
+
+ qapi_free_MigrationCapabilityStatusList(caps);
+}
+
void hmp_info_cpus(Monitor *mon)
{
CpuInfoList *cpu_list, *cpu;
@@ -756,6 +789,38 @@ void hmp_migrate_set_speed(Monitor *mon, const QDict *qdict)
qmp_migrate_set_speed(value, NULL);
}
+void hmp_migrate_set_capability(Monitor *mon, const QDict *qdict)
+{
+ const char *cap = qdict_get_str(qdict, "capability");
+ bool state = qdict_get_bool(qdict, "state");
+ Error *err = NULL;
+ MigrationCapabilityStatusList *caps = g_malloc0(sizeof(*caps));
+ int i;
+
+ for (i = 0; i < MIGRATION_CAPABILITY_MAX; i++) {
+ if (strcmp(cap, MigrationCapability_lookup[i]) == 0) {
+ caps->value = g_malloc0(sizeof(*caps->value));
+ caps->value->capability = i;
+ caps->value->state = state;
+ caps->next = NULL;
+ qmp_migrate_set_capabilities(caps, &err);
+ break;
+ }
+ }
+
+ if (i == MIGRATION_CAPABILITY_MAX) {
+ error_set(&err, QERR_INVALID_PARAMETER, cap);
+ }
+
+ qapi_free_MigrationCapabilityStatusList(caps);
+
+ 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 8442c22..f2a890f 100644
--- a/hmp.h
+++ b/hmp.h
@@ -26,6 +26,7 @@ void hmp_info_chardev(Monitor *mon);
void hmp_info_mice(Monitor *mon);
void hmp_info_migrate(Monitor *mon);
void hmp_info_migration_supported_capabilities(Monitor *mon);
+void hmp_info_migrate_capabilities(Monitor *mon);
void hmp_info_cpus(Monitor *mon);
void hmp_info_block(Monitor *mon);
void hmp_info_blockstats(Monitor *mon);
@@ -52,6 +53,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_capability(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 35444f7..d1a8d3a 100644
--- a/migration.c
+++ b/migration.c
@@ -113,6 +113,30 @@ uint64_t migrate_max_downtime(void)
return max_downtime;
}
+MigrationCapabilityStatusList *qmp_query_migrate_capabilities(Error **errp)
+{
+ MigrationCapabilityStatusList *head = NULL;
+ MigrationCapabilityStatusList *caps;
+ MigrationState *s = migrate_get_current();
+ int i;
+
+ for (i = 0; i < MIGRATION_CAPABILITY_MAX; i++) {
+ if (head == NULL) {
+ head = g_malloc0(sizeof(*caps));
+ caps = head;
+ } else {
+ caps->next = g_malloc0(sizeof(*caps));
+ caps = caps->next;
+ }
+ caps->value =
+ g_malloc(sizeof(*caps->value));
+ caps->value->capability = i;
+ caps->value->state = s->enabled_capabilities[i];
+ }
+
+ return head;
+}
+
MigrationInfo *qmp_query_migrate(Error **errp)
{
MigrationInfo *info = g_malloc0(sizeof(*info));
@@ -178,6 +202,22 @@ qmp_query_migration_supported_capabilities(Error **errp)
return caps_list;
}
+void qmp_migrate_set_capabilities(MigrationCapabilityStatusList *params,
+ Error **errp)
+{
+ MigrationState *s = migrate_get_current();
+ MigrationCapabilityStatusList *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)
@@ -387,10 +427,16 @@ 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;
diff --git a/migration.h b/migration.h
index 57572a6..713aae0 100644
--- a/migration.h
+++ b/migration.h
@@ -19,6 +19,7 @@
#include "notify.h"
#include "error.h"
#include "vmstate.h"
+#include "qapi-types.h"
struct MigrationParams {
bool blk;
@@ -39,6 +40,7 @@ struct MigrationState
void *opaque;
MigrationParams params;
int64_t total_time;
+ bool enabled_capabilities[MIGRATION_CAPABILITY_MAX];
};
void process_incoming_migration(QEMUFile *f);
diff --git a/monitor.c b/monitor.c
index 43f7df5..58d6e2a 100644
--- a/monitor.c
+++ b/monitor.c
@@ -2669,6 +2669,13 @@ static mon_cmd_t info_cmds[] = {
.mhandler.info = hmp_info_migration_supported_capabilities,
},
{
+ .name = "migrate_capabilities",
+ .args_type = "",
+ .params = "",
+ .help = "show current migration capabilities",
+ .mhandler.info = hmp_info_migrate_capabilities,
+ },
+ {
.name = "balloon",
.args_type = "",
.params = "",
diff --git a/qapi-schema.json b/qapi-schema.json
index 68d0fbb..f38dfc6 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -345,6 +345,38 @@
{ 'command': 'query-migration-supported-capabilities', 'returns': ['MigrationCapabilityStatus'] }
##
+# @migrate-set-capabilities
+#
+# Enable/Disable the following migration capabilities (like xbzrle)
+#
+# Since: 1.2
+##
+{ 'command': 'migrate-set-capabilities',
+ 'data': { 'capabilities': ['MigrationCapabilityStatus'] } }
+
+##
+# @MigrationParameters
+#
+# @capabilities: @MigrationCapabilityStatus list contain current migration
+# capabilities status
+# Since: 1.2
+##
+{ 'type': 'MigrationParameters',
+ 'data': {'capabilities': ['MigrationCapabilityStatus']} }
+
+
+##
+# @query-migrate-capabilities
+#
+# Returns information about the current migration capabilities status
+#
+# Returns: @MigrationCapabilitiesStatus
+#
+# Since: 1.2
+##
+{ 'command': 'query-migrate-capabilities', 'returns': ['MigrationCapabilityStatus']}
+
+##
# @MouseInfo:
#
# Information about a mouse device.
diff --git a/qmp-commands.hx b/qmp-commands.hx
index 16fbcef..e96a993 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -2166,6 +2166,55 @@ EQMP
},
SQMP
+migrate-set-capabilities
+-------
+
+Enable/Disable migration capabilities
+
+- "xbzrle": xbzrle support
+
+Arguments:
+
+Example:
+
+-> { "execute": "migrate-set-capabilities" , "arguments":
+ { "capabilities": [ { "capability": "xbzrle", "state": true } ] } }
+
+EQMP
+
+ {
+ .name = "migrate_set_capabilities",
+ .args_type = "capabilities:O",
+ .params = "capability:s,state:b",
+ .mhandler.cmd_new = qmp_marshal_input_migrate_set_capabilities,
+ },
+SQMP
+query-migrate-capabilities
+-------
+
+Query current migration capabilities
+
+- "capabilities": migration capabilities state
+ - "xbzrle" : XBZRLE state (json-bool)
+
+Arguments:
+
+Example:
+
+-> { "execute": "query-migrate-capabilities" }
+<- { "return": {
+ "capabilities" : [ { "capability" : "xbzrle", "state" : false } ]
+ }
+ }
+EQMP
+
+ {
+ .name = "query-migrate-capabilities",
+ .args_type = "",
+ .mhandler.cmd_new = qmp_marshal_input_query_migrate_capabilities,
+ },
+
+SQMP
query-balloon
-------------
--
1.7.7.6
^ permalink raw reply related [flat|nested] 32+ messages in thread
end of thread, other threads:[~2012-08-01 7:09 UTC | newest]
Thread overview: 32+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-07-31 18:54 [Qemu-devel] [PATCH 00/11] Migration next v8 Orit Wasserman
2012-07-31 18:54 ` [Qemu-devel] [PATCH 01/11] Add migration capabilities Orit Wasserman
2012-07-31 18:54 ` [Qemu-devel] [PATCH 02/11] Add migrate_set_parameter and query-migrate-parameters Orit Wasserman
2012-07-31 19:29 ` Eric Blake
2012-07-31 20:05 ` [Qemu-devel] [PATCH 02/11] Add migrate_set_capabilities and query-migrate-capabilities Orit Wasserman
2012-08-01 7:05 ` Orit Wasserman
2012-08-01 7:08 ` [Qemu-devel] [PATCH 02/11] Add migrate-set-capabilities " Orit Wasserman
2012-07-31 18:54 ` [Qemu-devel] [PATCH 03/11] Add XBZRLE documentation Orit Wasserman
2012-07-31 18:54 ` [Qemu-devel] [PATCH 04/11] Add cache handling functions Orit Wasserman
2012-07-31 18:54 ` [Qemu-devel] [PATCH 05/11] Add uleb encoding/decoding functions Orit Wasserman
2012-07-31 18:54 ` [Qemu-devel] [PATCH 06/11] Add xbzrle_encode_buffer and xbzrle_decode_buffer functions Orit Wasserman
2012-07-31 18:54 ` [Qemu-devel] [PATCH 07/11] Add XBZRLE to ram_save_block and ram_save_live Orit Wasserman
2012-07-31 18:54 ` [Qemu-devel] [PATCH 08/11] Add migrate_set_cachesize command Orit Wasserman
2012-07-31 18:54 ` [Qemu-devel] [PATCH 09/11] Add migration accounting for normal and duplicate pages Orit Wasserman
2012-07-31 18:54 ` [Qemu-devel] [PATCH 10/11] Add XBZRLE statistics Orit Wasserman
2012-07-31 18:54 ` [Qemu-devel] [PATCH 11/11] Restart optimization on stage3 update version Orit Wasserman
-- strict thread matches above, loose matches on Subject: below --
2012-07-29 9:42 [Qemu-devel] [PATCH 00/11] Migration next v7 Orit Wasserman
2012-07-29 9:42 ` [Qemu-devel] [PATCH 02/11] Add migrate_set_parameter and query-migrate-parameters Orit Wasserman
2012-07-30 17:41 ` Luiz Capitulino
2012-07-31 7:46 ` Orit Wasserman
2012-07-31 13:09 ` Luiz Capitulino
2012-07-31 8:03 ` Orit Wasserman
2012-07-30 18:11 ` Eric Blake
2012-07-30 18:15 ` Luiz Capitulino
2012-07-30 19:12 ` Juan Quintela
2012-07-30 19:24 ` Eric Blake
2012-07-30 19:37 ` Anthony Liguori
2012-07-30 20:21 ` Juan Quintela
2012-07-30 19:45 ` Anthony Liguori
2012-07-30 19:58 ` Luiz Capitulino
2012-07-30 20:04 ` Anthony Liguori
2012-07-30 20:20 ` Luiz Capitulino
2012-07-25 14:50 [Qemu-devel] [PATCH 00/11] Migration next v6 Orit Wasserman
2012-07-25 14:50 ` [Qemu-devel] [PATCH 02/11] Add migrate_set_parameter and query-migrate-parameters Orit Wasserman
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).