Alex Bligh
2013-Feb-19 13:15 UTC
[PATCHv4 00/11] libxl: Enabling live-migrate on HVM on qemu-xen device model in 4.2 - libxl patchset
This patch series consists of 2 parts: * 11 patches to libxl * 5 patches to QEMU The 11 patches to libxl are unchanged since version 3 of the patch, but have Acked-By lines reintroduced. The 5 patches to QEMU are unchanged since version 2 of the patch. These patches enable live-migrate on HVM using the upstream qemu-xen device model under Xen 4.2. Currently this is unimplemented. In the main they are backports of patches in xen-unstable, thought the QEMU side in particular needed some fiddling. I would suggest these patches should be included in 4.2.2. You can find these on Github at: https://github.com/abligh/xen-4.2-live-migrate/commits/PATCHv4 Or on the PATCHv4 branch of this repository: https://github.com/abligh/xen-4.2-live-migrate.git Alex Bligh (11): libxl_json: Export json_object related function. libxl_json: Remove JSON_ERROR from enum. libxl_json: Replace JSON_TRUE/FALSE by JSON_BOOL. libxl_json: Introduce libxl__json_object_to_yajl_gen. libxl_qmp: Introduces helpers to create an argument list. libxl_qmp: Use qmp_parameters_* functions for param list of a QMP command. libxl_qmp: Simplify run of single QMP commands. libxl_qmp: Introduce libxl__qmp_set_global_dirty_log. libxl_dom: Call the right switch logdirty for the right DM. libxl: libxl__qmp_save: Add filename as JSON parameter to xen-save-devices-state libxl: Allow migration with qemu-xen. tools/libxl/libxl.c | 17 ---- tools/libxl/libxl_dom.c | 45 +++++++++- tools/libxl/libxl_internal.h | 35 ++++++- tools/libxl/libxl_json.c | 94 +++++++++++++++---- tools/libxl/libxl_qmp.c | 209 +++++++++++++++++++++--------------------- 5 files changed, 253 insertions(+), 147 deletions(-) All this patch series: Acked-by: Ian Jackson <ian.jackson@eu.citrix.com> -- 1.7.4.1
Alex Bligh
2013-Feb-19 13:15 UTC
[PATCHv4 01/11] libxl_json: Export json_object related function.
Export libxl__json_object_alloc and libxl__json_object_append_to to use them in a later patch. Backported from xen-unstable patch: : User Anthony PERARD <anthony.perard@citrix.com> : Date 1349693129 -3600 : Node ID c9b80c7f8db1a5d26906a2298c481bf7e87fda94 : Parent 93e3e6a33e0a1ec9f92fc575334caa35e6dbc757 Acked-by: Ian Jackson <ian.jackson@eu.citrix.com> Signed-off-by: Alex Bligh <alex@alex.org.uk> --- tools/libxl/libxl_internal.h | 14 ++++++++++++-- tools/libxl/libxl_json.c | 32 ++++++++++++++++---------------- 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h index a135cd7..2959527 100644 *** a/tools/libxl/libxl_internal.h --- b/tools/libxl/libxl_internal.h *************** *** 1512,1517 **** --- 1512,1526 ---- return -1; } + /* + * NOGC can be used with those json_object functions, but the + * libxl__json_object* will need to be freed with libxl__json_object_free. + */ + _hidden libxl__json_object *libxl__json_object_alloc(libxl__gc *gc_opt, + libxl__json_node_type type); + _hidden int libxl__json_object_append_to(libxl__gc *gc_opt, + libxl__json_object *obj, + libxl__json_object *dst); _hidden libxl__json_object *libxl__json_array_get(const libxl__json_object *o, int i); _hidden *************** *** 1520,1528 **** _hidden const libxl__json_object *libxl__json_map_get(const char *key, const libxl__json_object *o, libxl__json_node_type expected_type); ! _hidden void libxl__json_object_free(libxl__gc *gc, libxl__json_object *obj); ! _hidden libxl__json_object *libxl__json_parse(libxl__gc *gc, const char *s); /* Based on /local/domain/$domid/dm-version xenstore key * default is qemu xen traditional */ --- 1529,1538 ---- _hidden const libxl__json_object *libxl__json_map_get(const char *key, const libxl__json_object *o, libxl__json_node_type expected_type); ! _hidden void libxl__json_object_free(libxl__gc *gc_opt, ! libxl__json_object *obj); ! _hidden libxl__json_object *libxl__json_parse(libxl__gc *gc_opt, const char *s); /* Based on /local/domain/$domid/dm-version xenstore key * default is qemu xen traditional */ diff --git a/tools/libxl/libxl_json.c b/tools/libxl/libxl_json.c index caa8312..0b0cf2f 100644 *** a/tools/libxl/libxl_json.c --- b/tools/libxl/libxl_json.c *************** *** 205,211 **** * libxl__json_object helper functions */ ! static libxl__json_object *json_object_alloc(libxl__gc *gc, libxl__json_node_type type) { libxl__json_object *obj; --- 205,211 ---- * libxl__json_object helper functions */ ! libxl__json_object *libxl__json_object_alloc(libxl__gc *gc, libxl__json_node_type type) { libxl__json_object *obj; *************** *** 236,242 **** return obj; } ! static int json_object_append_to(libxl__gc *gc, libxl__json_object *obj, libxl__json_object *dst) { --- 236,242 ---- return obj; } ! int libxl__json_object_append_to(libxl__gc *gc, libxl__json_object *obj, libxl__json_object *dst) { *************** *** 393,402 **** DEBUG_GEN(ctx, null); ! if ((obj = json_object_alloc(ctx->gc, JSON_NULL)) == NULL) return 0; ! if (json_object_append_to(ctx->gc, obj, ctx->current) == -1) { libxl__json_object_free(ctx->gc, obj); return 0; } --- 393,402 ---- DEBUG_GEN(ctx, null); ! if ((obj = libxl__json_object_alloc(ctx->gc, JSON_NULL)) == NULL) return 0; ! if (libxl__json_object_append_to(ctx->gc, obj, ctx->current) == -1) { libxl__json_object_free(ctx->gc, obj); return 0; } *************** *** 411,421 **** DEBUG_GEN_VALUE(ctx, bool, boolean); ! if ((obj = json_object_alloc(ctx->gc, boolean ? JSON_TRUE : JSON_FALSE)) == NULL) return 0; ! if (json_object_append_to(ctx->gc, obj, ctx->current) == -1) { libxl__json_object_free(ctx->gc, obj); return 0; } --- 411,421 ---- DEBUG_GEN_VALUE(ctx, bool, boolean); ! if ((obj = libxl__json_object_alloc(ctx->gc, boolean ? JSON_TRUE : JSON_FALSE)) == NULL) return 0; ! if (libxl__json_object_append_to(ctx->gc, obj, ctx->current) == -1) { libxl__json_object_free(ctx->gc, obj); return 0; } *************** *** 448,454 **** goto error; } ! if ((obj = json_object_alloc(ctx->gc, JSON_DOUBLE)) == NULL) return 0; obj->u.d = d; } else { --- 448,454 ---- goto error; } ! if ((obj = libxl__json_object_alloc(ctx->gc, JSON_DOUBLE)) == NULL) return 0; obj->u.d = d; } else { *************** *** 458,464 **** goto error; } ! if ((obj = json_object_alloc(ctx->gc, JSON_INTEGER)) == NULL) return 0; obj->u.i = i; } --- 458,464 ---- goto error; } ! if ((obj = libxl__json_object_alloc(ctx->gc, JSON_INTEGER)) == NULL) return 0; obj->u.i = i; } *************** *** 466,472 **** error: /* If the conversion fail, we just store the original string. */ ! if ((obj = json_object_alloc(ctx->gc, JSON_NUMBER)) == NULL) return 0; t = malloc(len + 1); --- 466,472 ---- error: /* If the conversion fail, we just store the original string. */ ! if ((obj = libxl__json_object_alloc(ctx->gc, JSON_NUMBER)) == NULL) return 0; t = malloc(len + 1); *************** *** 481,487 **** obj->u.string = t; out: ! if (json_object_append_to(ctx->gc, obj, ctx->current) == -1) { libxl__json_object_free(ctx->gc, obj); return 0; } --- 481,487 ---- obj->u.string = t; out: ! if (libxl__json_object_append_to(ctx->gc, obj, ctx->current) == -1) { libxl__json_object_free(ctx->gc, obj); return 0; } *************** *** 508,520 **** strncpy(t, (const char *) str, len); t[len] = 0; ! if ((obj = json_object_alloc(ctx->gc, JSON_STRING)) == NULL) { free(t); return 0; } obj->u.string = t; ! if (json_object_append_to(ctx->gc, obj, ctx->current) == -1) { libxl__json_object_free(ctx->gc, obj); return 0; } --- 508,520 ---- strncpy(t, (const char *) str, len); t[len] = 0; ! if ((obj = libxl__json_object_alloc(ctx->gc, JSON_STRING)) == NULL) { free(t); return 0; } obj->u.string = t; ! if (libxl__json_object_append_to(ctx->gc, obj, ctx->current) == -1) { libxl__json_object_free(ctx->gc, obj); return 0; } *************** *** 573,583 **** DEBUG_GEN(ctx, map_open); ! if ((obj = json_object_alloc(ctx->gc, JSON_MAP)) == NULL) return 0; if (ctx->current) { ! if (json_object_append_to(ctx->gc, obj, ctx->current) == -1) { libxl__json_object_free(ctx->gc, obj); return 0; } --- 573,583 ---- DEBUG_GEN(ctx, map_open); ! if ((obj = libxl__json_object_alloc(ctx->gc, JSON_MAP)) == NULL) return 0; if (ctx->current) { ! if (libxl__json_object_append_to(ctx->gc, obj, ctx->current) == -1) { libxl__json_object_free(ctx->gc, obj); return 0; } *************** *** 615,625 **** DEBUG_GEN(ctx, array_open); ! if ((obj = json_object_alloc(ctx->gc, JSON_ARRAY)) == NULL) return 0; if (ctx->current) { ! if (json_object_append_to(ctx->gc, obj, ctx->current) == -1) { libxl__json_object_free(ctx->gc, obj); return 0; } - - --- 615,625 ---- DEBUG_GEN(ctx, array_open); ! if ((obj = libxl__json_object_alloc(ctx->gc, JSON_ARRAY)) == NULL) return 0; if (ctx->current) { ! if (libxl__json_object_append_to(ctx->gc, obj, ctx->current) == -1) { libxl__json_object_free(ctx->gc, obj); return 0; } 1.7.4.1
This value from libxl__json_node_type is never used. Backported from xen-unstable patch: : HG changeset patch : User Anthony PERARD <anthony.perard@citrix.com> : Date 1349693130 -3600 : Node ID 4a6d5d8cba4fc44f9bbda201188885868604b8e8 : Parent c9b80c7f8db1a5d26906a2298c481bf7e87fda94 Acked-by: Ian Jackson <ian.jackson@eu.citrix.com> Signed-off-by: Alex Bligh <alex@alex.org.uk> --- tools/libxl/libxl_internal.h | 1 - 1 files changed, 0 insertions(+), 1 deletions(-) diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h index 2959527..5b285d4 100644 --- a/tools/libxl/libxl_internal.h +++ b/tools/libxl/libxl_internal.h @@ -1428,7 +1428,6 @@ _hidden yajl_gen_status libxl__yajl_gen_asciiz(yajl_gen hand, const char *str); _hidden yajl_gen_status libxl__yajl_gen_enum(yajl_gen hand, const char *str); typedef enum { - JSON_ERROR, JSON_NULL, JSON_TRUE, JSON_FALSE, -- 1.7.4.1
Alex Bligh
2013-Feb-19 13:15 UTC
[PATCHv4 03/11] libxl_json: Replace JSON_TRUE/FALSE by JSON_BOOL.
Those two JSON_TRUE and JSON_FALSE were types of node. But it''s better to have a unique JSON_BOOL type. Backported from xen-unstable patch: : HG changeset patch : User Anthony PERARD <anthony.perard@citrix.com> : Date 1349693131 -3600 : Node ID 3f71aab0e2774ded0c5a03436c364fb031ba9aa0 : Parent 4a6d5d8cba4fc44f9bbda201188885868604b8e8 Acked-by: Ian Jackson <ian.jackson@eu.citrix.com> Signed-off-by: Alex Bligh <alex@alex.org.uk> --- tools/libxl/libxl_internal.h | 15 +++++++++++++-- tools/libxl/libxl_json.c | 3 +-- tools/libxl/libxl_qmp.c | 3 ++- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h index 5b285d4..7dbd8af 100644 --- a/tools/libxl/libxl_internal.h +++ b/tools/libxl/libxl_internal.h @@ -1429,8 +1429,7 @@ _hidden yajl_gen_status libxl__yajl_gen_enum(yajl_gen hand, const char *str); typedef enum { JSON_NULL, - JSON_TRUE, - JSON_FALSE, + JSON_BOOL, JSON_INTEGER, JSON_DOUBLE, /* number is store in string, it''s too big to be a long long or a double */ @@ -1444,6 +1443,7 @@ typedef enum { typedef struct libxl__json_object { libxl__json_node_type type; union { + bool b; long long i; double d; char *string; @@ -1462,6 +1462,10 @@ typedef struct { typedef struct libxl__yajl_ctx libxl__yajl_ctx; +static inline bool libxl__json_object_is_bool(const libxl__json_object *o) +{ + return o != NULL && o->type == JSON_BOOL; +} static inline bool libxl__json_object_is_string(const libxl__json_object *o) { return o != NULL && o->type == JSON_STRING; @@ -1479,6 +1483,13 @@ static inline bool libxl__json_object_is_array(const libxl__json_object *o) return o != NULL && o->type == JSON_ARRAY; } +static inline bool libxl__json_object_get_bool(const libxl__json_object *o) +{ + if (libxl__json_object_is_bool(o)) + return o->u.b; + else + return false; +} static inline const char *libxl__json_object_get_string(const libxl__json_object *o) { diff --git a/tools/libxl/libxl_json.c b/tools/libxl/libxl_json.c index 0b0cf2f..98db465 100644 --- a/tools/libxl/libxl_json.c +++ b/tools/libxl/libxl_json.c @@ -411,8 +411,7 @@ static int json_callback_boolean(void *opaque, int boolean) DEBUG_GEN_VALUE(ctx, bool, boolean); - if ((obj = libxl__json_object_alloc(ctx->gc, - boolean ? JSON_TRUE : JSON_FALSE)) == NULL) + if ((obj = libxl__json_object_alloc(ctx->gc, JSON_BOOL)) == NULL) return 0; if (libxl__json_object_append_to(ctx->gc, obj, ctx->current) == -1) { diff --git a/tools/libxl/libxl_qmp.c b/tools/libxl/libxl_qmp.c index e33b130..9e86c35 100644 --- a/tools/libxl/libxl_qmp.c +++ b/tools/libxl/libxl_qmp.c @@ -178,7 +178,8 @@ static int qmp_register_vnc_callback(libxl__qmp_handler *qmp, goto out; } - if (libxl__json_map_get("enabled", o, JSON_FALSE)) { + obj = libxl__json_map_get("enabled", o, JSON_BOOL); + if (!obj || !libxl__json_object_get_bool(obj)) { rc = 0; goto out; } -- 1.7.4.1
Alex Bligh
2013-Feb-19 13:15 UTC
[PATCHv4 04/11] libxl_json: Introduce libxl__json_object_to_yajl_gen.
This function converts a libxl__json_object to yajl by calling every yajl_gen_* function on a preallocated yajl_gen hand. This helps to integrate a json_object into an already existing yajl_gen tree. This function is used in a later patch. Backported from xen-unstable patch: : HG changeset patch : User Anthony PERARD <anthony.perard@citrix.com> : Date 1349693132 -3600 : Node ID 74dee58cfc0d2d6594f388db3b4d2ce91d1bb204 : Parent 3f71aab0e2774ded0c5a03436c364fb031ba9aa0 Acked-by: Ian Jackson <ian.jackson@eu.citrix.com> Signed-off-by: Alex Bligh <alex@alex.org.uk> --- tools/libxl/libxl_internal.h | 3 ++ tools/libxl/libxl_json.c | 61 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 0 deletions(-) diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h index 7dbd8af..b00ff61 100644 --- a/tools/libxl/libxl_internal.h +++ b/tools/libxl/libxl_internal.h @@ -1539,6 +1539,9 @@ libxl__json_map_node *libxl__json_map_node_get(const libxl__json_object *o, _hidden const libxl__json_object *libxl__json_map_get(const char *key, const libxl__json_object *o, libxl__json_node_type expected_type); +_hidden yajl_status libxl__json_object_to_yajl_gen(libxl__gc *gc_opt, + yajl_gen hand, + libxl__json_object *param); _hidden void libxl__json_object_free(libxl__gc *gc_opt, libxl__json_object *obj); diff --git a/tools/libxl/libxl_json.c b/tools/libxl/libxl_json.c index 98db465..72b52e8 100644 --- a/tools/libxl/libxl_json.c +++ b/tools/libxl/libxl_json.c @@ -381,6 +381,67 @@ const libxl__json_object *libxl__json_map_get(const char *key, return NULL; } +yajl_status libxl__json_object_to_yajl_gen(libxl__gc *gc, + yajl_gen hand, + libxl__json_object *obj) +{ + int idx = 0; + yajl_status rc; + + switch (obj->type) { + case JSON_NULL: + return yajl_gen_null(hand); + case JSON_BOOL: + return yajl_gen_bool(hand, obj->u.b); + case JSON_INTEGER: + return yajl_gen_integer(hand, obj->u.i); + case JSON_DOUBLE: + return yajl_gen_double(hand, obj->u.d); + case JSON_NUMBER: + return yajl_gen_number(hand, obj->u.string, strlen(obj->u.string)); + case JSON_STRING: + return libxl__yajl_gen_asciiz(hand, obj->u.string); + case JSON_MAP: { + libxl__json_map_node *node = NULL; + + rc = yajl_gen_map_open(hand); + if (rc != yajl_status_ok) + return rc; + for (idx = 0; idx < obj->u.map->count; idx++) { + if (flexarray_get(obj->u.map, idx, (void**)&node) != 0) + break; + + rc = libxl__yajl_gen_asciiz(hand, node->map_key); + if (rc != yajl_status_ok) + return rc; + rc = libxl__json_object_to_yajl_gen(gc, hand, node->obj); + if (rc != yajl_status_ok) + return rc; + } + return yajl_gen_map_close(hand); + } + case JSON_ARRAY: { + libxl__json_object *node = NULL; + + rc = yajl_gen_array_open(hand); + if (rc != yajl_status_ok) + return rc; + for (idx = 0; idx < obj->u.array->count; idx++) { + if (flexarray_get(obj->u.array, idx, (void**)&node) != 0) + break; + rc = libxl__json_object_to_yajl_gen(gc, hand, node); + if (rc != yajl_status_ok) + return rc; + } + return yajl_gen_array_close(hand); + } + case JSON_ANY: + /* JSON_ANY is not a valid value for obj->type. */ + ; + } + abort(); +} + /* * JSON callbacks -- 1.7.4.1
Alex Bligh
2013-Feb-19 13:15 UTC
[PATCHv4 05/11] libxl_qmp: Introduces helpers to create an argument list.
Those functions will be used to create a "list" of parameters that contain more than just strings. This list is converted by qmp_send to a string to be sent to QEMU. Those functions will be used in the next two patches, so right now there are not compiled. Backported from xen-unstable patch: : HG changeset patch : User Anthony PERARD <anthony.perard@citrix.com> : Date 1349693132 -3600 : Node ID 6f7847729f0f42614de516d15257ede7243f995f : Parent 74dee58cfc0d2d6594f388db3b4d2ce91d1bb204 Acked-by: Ian Jackson <ian.jackson@eu.citrix.com> Signed-off-by: Alex Bligh <alex@alex.org.uk> --- tools/libxl/libxl_qmp.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 51 insertions(+), 0 deletions(-) diff --git a/tools/libxl/libxl_qmp.c b/tools/libxl/libxl_qmp.c index 9e86c35..827f1b7 100644 --- a/tools/libxl/libxl_qmp.c +++ b/tools/libxl/libxl_qmp.c @@ -624,6 +624,57 @@ static void qmp_free_handler(libxl__qmp_handler *qmp) free(qmp); } +#if 0 +/* + * QMP Parameters Helpers + */ +static void qmp_parameters_common_add(libxl__gc *gc, + libxl__json_object **param, + const char *name, + libxl__json_object *obj) +{ + libxl__json_map_node *arg = NULL; + + if (!*param) { + *param = libxl__json_object_alloc(gc, JSON_MAP); + } + + arg = libxl__zalloc(gc, sizeof(*arg)); + + arg->map_key = libxl__strdup(gc, name); + arg->obj = obj; + + flexarray_append((*param)->u.map, arg); +} + +static void qmp_parameters_add_string(libxl__gc *gc, + libxl__json_object **param, + const char *name, const char *argument) +{ + libxl__json_object *obj; + + obj = libxl__json_object_alloc(gc, JSON_STRING); + obj->u.string = libxl__strdup(gc, argument); + + qmp_parameters_common_add(gc, param, name, obj); +} + +static void qmp_parameters_add_bool(libxl__gc *gc, + libxl__json_object **param, + const char *name, bool b) +{ + libxl__json_object *obj; + + obj = libxl__json_object_alloc(gc, JSON_BOOL); + obj->u.b = b; + qmp_parameters_common_add(gc, param, name, obj); +} + +#define QMP_PARAMETERS_SPRINTF(args, name, format, ...) \ + qmp_parameters_add_string(gc, args, name, \ + libxl__sprintf(gc, format, __VA_ARGS__)) +#endif + /* * API */ -- 1.7.4.1
Alex Bligh
2013-Feb-19 13:15 UTC
[PATCHv4 06/11] libxl_qmp: Use qmp_parameters_* functions for param list of a QMP command.
Backported from xen-unstable patch: : HG changeset patch : User Anthony PERARD <anthony.perard@citrix.com> : Date 1349693133 -3600 : Node ID be5d014f91dfbd67afacc3385c265243794a246f : Parent 6f7847729f0f42614de516d15257ede7243f995f Acked-by: Ian Jackson <ian.jackson@eu.citrix.com> Signed-off-by: Alex Bligh <alex@alex.org.uk> --- tools/libxl/libxl_qmp.c | 89 ++++++++++++++++------------------------------- 1 files changed, 30 insertions(+), 59 deletions(-) diff --git a/tools/libxl/libxl_qmp.c b/tools/libxl/libxl_qmp.c index 827f1b7..605e8f3 100644 --- a/tools/libxl/libxl_qmp.c +++ b/tools/libxl/libxl_qmp.c @@ -78,7 +78,7 @@ struct libxl__qmp_handler { }; static int qmp_send(libxl__qmp_handler *qmp, - const char *cmd, libxl_key_value_list *args, + const char *cmd, libxl__json_object *args, qmp_callback_t callback, void *opaque, qmp_request_context *context); @@ -503,7 +503,7 @@ static int qmp_next(libxl__gc *gc, libxl__qmp_handler *qmp) } static char *qmp_send_prepare(libxl__gc *gc, libxl__qmp_handler *qmp, - const char *cmd, libxl_key_value_list *args, + const char *cmd, libxl__json_object *args, qmp_callback_t callback, void *opaque, qmp_request_context *context) { @@ -527,7 +527,7 @@ static char *qmp_send_prepare(libxl__gc *gc, libxl__qmp_handler *qmp, yajl_gen_integer(hand, ++qmp->last_id_used); if (args) { libxl__yajl_gen_asciiz(hand, "arguments"); - libxl_key_value_list_gen_json(hand, args); + libxl__json_object_to_yajl_gen(gc, hand, args); } yajl_gen_map_close(hand); @@ -561,7 +561,7 @@ out: } static int qmp_send(libxl__qmp_handler *qmp, - const char *cmd, libxl_key_value_list *args, + const char *cmd, libxl__json_object *args, qmp_callback_t callback, void *opaque, qmp_request_context *context) { @@ -589,7 +589,7 @@ out: } static int qmp_synchronous_send(libxl__qmp_handler *qmp, const char *cmd, - libxl_key_value_list *args, + libxl__json_object *args, qmp_callback_t callback, void *opaque, int ask_timeout) { @@ -624,7 +624,6 @@ static void qmp_free_handler(libxl__qmp_handler *qmp) free(qmp); } -#if 0 /* * QMP Parameters Helpers */ @@ -659,6 +658,7 @@ static void qmp_parameters_add_string(libxl__gc *gc, qmp_parameters_common_add(gc, param, name, obj); } +#if 0 static void qmp_parameters_add_bool(libxl__gc *gc, libxl__json_object **param, const char *name, bool b) @@ -669,11 +669,11 @@ static void qmp_parameters_add_bool(libxl__gc *gc, obj->u.b = b; qmp_parameters_common_add(gc, param, name, obj); } +#endif #define QMP_PARAMETERS_SPRINTF(args, name, format, ...) \ qmp_parameters_add_string(gc, args, name, \ libxl__sprintf(gc, format, __VA_ARGS__)) -#endif /* * API @@ -801,8 +801,7 @@ out: int libxl__qmp_pci_add(libxl__gc *gc, int domid, libxl_device_pci *pcidev) { libxl__qmp_handler *qmp = NULL; - flexarray_t *parameters = NULL; - libxl_key_value_list args = NULL; + libxl__json_object *args = NULL; char *hostaddr = NULL; int rc = 0; @@ -815,31 +814,22 @@ int libxl__qmp_pci_add(libxl__gc *gc, int domid, libxl_device_pci *pcidev) if (!hostaddr) return -1; - parameters = flexarray_make(6, 1); - flexarray_append_pair(parameters, "driver", "xen-pci-passthrough"); - flexarray_append_pair(parameters, "id", - libxl__sprintf(gc, PCI_PT_QDEV_ID, - pcidev->bus, pcidev->dev, - pcidev->func)); - flexarray_append_pair(parameters, "hostaddr", hostaddr); + qmp_parameters_add_string(gc, &args, "driver", "xen-pci-passthrough"); + QMP_PARAMETERS_SPRINTF(&args, "id", PCI_PT_QDEV_ID, + pcidev->bus, pcidev->dev, pcidev->func); + qmp_parameters_add_string(gc, &args, "hostaddr", hostaddr); if (pcidev->vdevfn) { - flexarray_append_pair(parameters, "addr", - libxl__sprintf(gc, "%x.%x", - PCI_SLOT(pcidev->vdevfn), - PCI_FUNC(pcidev->vdevfn))); + QMP_PARAMETERS_SPRINTF(&args, "addr", "%x.%x", + PCI_SLOT(pcidev->vdevfn), PCI_FUNC(pcidev->vdevfn)); } - args = libxl__xs_kvs_of_flexarray(gc, parameters, parameters->count); - if (!args) - return -1; - rc = qmp_synchronous_send(qmp, "device_add", &args, + rc = qmp_synchronous_send(qmp, "device_add", args, NULL, NULL, qmp->timeout); if (rc == 0) { rc = qmp_synchronous_send(qmp, "query-pci", NULL, pci_add_callback, pcidev, qmp->timeout); } - flexarray_free(parameters); libxl__qmp_close(qmp); return rc; } @@ -847,24 +837,18 @@ int libxl__qmp_pci_add(libxl__gc *gc, int domid, libxl_device_pci *pcidev) static int qmp_device_del(libxl__gc *gc, int domid, char *id) { libxl__qmp_handler *qmp = NULL; - flexarray_t *parameters = NULL; - libxl_key_value_list args = NULL; + libxl__json_object *args = NULL; int rc = 0; qmp = libxl__qmp_initialize(gc, domid); if (!qmp) return ERROR_FAIL; - parameters = flexarray_make(2, 1); - flexarray_append_pair(parameters, "id", id); - args = libxl__xs_kvs_of_flexarray(gc, parameters, parameters->count); - if (!args) - return ERROR_NOMEM; + qmp_parameters_add_string(gc, &args, "id", id); - rc = qmp_synchronous_send(qmp, "device_del", &args, + rc = qmp_synchronous_send(qmp, "device_del", args, NULL, NULL, qmp->timeout); - flexarray_free(parameters); libxl__qmp_close(qmp); return rc; } @@ -882,56 +866,43 @@ int libxl__qmp_pci_del(libxl__gc *gc, int domid, libxl_device_pci *pcidev) int libxl__qmp_save(libxl__gc *gc, int domid, const char *filename) { libxl__qmp_handler *qmp = NULL; - flexarray_t *parameters = NULL; - libxl_key_value_list args = NULL; + libxl__json_object *args = NULL; int rc = 0; qmp = libxl__qmp_initialize(gc, domid); if (!qmp) return ERROR_FAIL; - parameters = flexarray_make(2, 1); - if (!parameters) { - rc = ERROR_NOMEM; - goto out; - } - flexarray_append_pair(parameters, "filename", (char *)filename); - args = libxl__xs_kvs_of_flexarray(gc, parameters, parameters->count); + qmp_parameters_add_string(gc, &args, "filename", (char *)filename); if (!args) { rc = ERROR_NOMEM; - goto out2; + goto out; } - rc = qmp_synchronous_send(qmp, "xen-save-devices-state", &args, + rc = qmp_synchronous_send(qmp, "xen-save-devices-state", args, NULL, NULL, qmp->timeout); -out2: - flexarray_free(parameters); out: libxl__qmp_close(qmp); return rc; + } static int qmp_change(libxl__gc *gc, libxl__qmp_handler *qmp, char *device, char *target, char *arg) { - flexarray_t *parameters = NULL; - libxl_key_value_list args = NULL; + libxl__json_object *args = NULL; int rc = 0; - parameters = flexarray_make(6, 1); - flexarray_append_pair(parameters, "device", device); - flexarray_append_pair(parameters, "target", target); - if (arg) - flexarray_append_pair(parameters, "arg", arg); - args = libxl__xs_kvs_of_flexarray(gc, parameters, parameters->count); - if (!args) - return ERROR_NOMEM; + qmp_parameters_add_string(gc, &args, "device", device); + qmp_parameters_add_string(gc, &args, "target", target); + if (arg) { + qmp_parameters_add_string(gc, &args, "arg", arg); + } - rc = qmp_synchronous_send(qmp, "change", &args, + rc = qmp_synchronous_send(qmp, "change", args, NULL, NULL, qmp->timeout); - flexarray_free(parameters); return rc; } -- 1.7.4.1
Alex Bligh
2013-Feb-19 13:15 UTC
[PATCHv4 07/11] libxl_qmp: Simplify run of single QMP commands.
This new function connects to QEMU, sends the command and disconnects. Backport of xen-unstable patch: : HG changeset patch : User Anthony PERARD <anthony.perard@citrix.com> : Date 1349693134 -3600 : Node ID f3890916496445c97d6778d6c986b0270ff707f2 : Parent be5d014f91dfbd67afacc3385c265243794a246f Acked-by: Ian Jackson <ian.jackson@eu.citrix.com> Signed-off-by: Alex Bligh <alex@alex.org.uk> --- tools/libxl/libxl_qmp.c | 77 +++++++++++++--------------------------------- 1 files changed, 22 insertions(+), 55 deletions(-) diff --git a/tools/libxl/libxl_qmp.c b/tools/libxl/libxl_qmp.c index 605e8f3..b09bf13 100644 --- a/tools/libxl/libxl_qmp.c +++ b/tools/libxl/libxl_qmp.c @@ -798,6 +798,23 @@ out: return rc; } +static int qmp_run_command(libxl__gc *gc, int domid, + const char *cmd, libxl__json_object *args, + qmp_callback_t callback, void *opaque) +{ + libxl__qmp_handler *qmp = NULL; + int rc = 0; + + qmp = libxl__qmp_initialize(gc, domid); + if (!qmp) + return ERROR_FAIL; + + rc = qmp_synchronous_send(qmp, cmd, args, callback, opaque, qmp->timeout); + + libxl__qmp_close(qmp); + return rc; +} + int libxl__qmp_pci_add(libxl__gc *gc, int domid, libxl_device_pci *pcidev) { libxl__qmp_handler *qmp = NULL; @@ -836,21 +853,10 @@ int libxl__qmp_pci_add(libxl__gc *gc, int domid, libxl_device_pci *pcidev) static int qmp_device_del(libxl__gc *gc, int domid, char *id) { - libxl__qmp_handler *qmp = NULL; libxl__json_object *args = NULL; - int rc = 0; - - qmp = libxl__qmp_initialize(gc, domid); - if (!qmp) - return ERROR_FAIL; qmp_parameters_add_string(gc, &args, "id", id); - - rc = qmp_synchronous_send(qmp, "device_del", args, - NULL, NULL, qmp->timeout); - - libxl__qmp_close(qmp); - return rc; + return qmp_run_command(gc, domid, "device_del", args, NULL, NULL); } int libxl__qmp_pci_del(libxl__gc *gc, int domid, libxl_device_pci *pcidev) @@ -865,27 +871,10 @@ int libxl__qmp_pci_del(libxl__gc *gc, int domid, libxl_device_pci *pcidev) int libxl__qmp_save(libxl__gc *gc, int domid, const char *filename) { - libxl__qmp_handler *qmp = NULL; libxl__json_object *args = NULL; - int rc = 0; - - qmp = libxl__qmp_initialize(gc, domid); - if (!qmp) - return ERROR_FAIL; - - qmp_parameters_add_string(gc, &args, "filename", (char *)filename); - if (!args) { - rc = ERROR_NOMEM; - goto out; - } - - rc = qmp_synchronous_send(qmp, "xen-save-devices-state", args, - NULL, NULL, qmp->timeout); - -out: - libxl__qmp_close(qmp); - return rc; + return qmp_run_command(gc, domid, "xen-save-devices-state", args, + NULL, NULL); } static int qmp_change(libxl__gc *gc, libxl__qmp_handler *qmp, @@ -908,34 +897,12 @@ static int qmp_change(libxl__gc *gc, libxl__qmp_handler *qmp, int libxl__qmp_stop(libxl__gc *gc, int domid) { - libxl__qmp_handler *qmp = NULL; - int rc = 0; - - qmp = libxl__qmp_initialize(gc, domid); - if (!qmp) - return ERROR_FAIL; - - rc = qmp_synchronous_send(qmp, "stop", NULL, - NULL, NULL, qmp->timeout); - - libxl__qmp_close(qmp); - return rc; + return qmp_run_command(gc, domid, "stop", NULL, NULL, NULL); } int libxl__qmp_resume(libxl__gc *gc, int domid) { - libxl__qmp_handler *qmp = NULL; - int rc = 0; - - qmp = libxl__qmp_initialize(gc, domid); - if (!qmp) - return ERROR_FAIL; - - rc = qmp_synchronous_send(qmp, "cont", NULL, - NULL, NULL, qmp->timeout); - - libxl__qmp_close(qmp); - return rc; + return qmp_run_command(gc, domid, "cont", NULL, NULL, NULL); } int libxl__qmp_initializations(libxl__gc *gc, uint32_t domid, -- 1.7.4.1
Alex Bligh
2013-Feb-19 13:15 UTC
[PATCHv4 08/11] libxl_qmp: Introduce libxl__qmp_set_global_dirty_log.
This function will enable or disable the global dirty log on QEMU, used during a migration. Backport of xen-unstable patch: : HG changeset patch : User Anthony PERARD <anthony.perard@citrix.com> : Date 1349693135 -3600 : Node ID d4aec9eff7e6d15c2805957af620c82555553b3e : Parent f3890916496445c97d6778d6c986b0270ff707f2 Acked-by: Ian Jackson <ian.jackson@eu.citrix.com> Signed-off-by: Alex Bligh <alex@alex.org.uk> --- tools/libxl/libxl_internal.h | 2 ++ tools/libxl/libxl_qmp.c | 12 ++++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h index b00ff61..f658562 100644 --- a/tools/libxl/libxl_internal.h +++ b/tools/libxl/libxl_internal.h @@ -1400,6 +1400,8 @@ _hidden int libxl__qmp_stop(libxl__gc *gc, int domid); _hidden int libxl__qmp_resume(libxl__gc *gc, int domid); /* Save current QEMU state into fd. */ _hidden int libxl__qmp_save(libxl__gc *gc, int domid, const char *filename); +/* Set dirty bitmap logging status */ +_hidden int libxl__qmp_set_global_dirty_log(libxl__gc *gc, int domid, bool enable); /* close and free the QMP handler */ _hidden void libxl__qmp_close(libxl__qmp_handler *qmp); /* remove the socket file, if the file has already been removed, diff --git a/tools/libxl/libxl_qmp.c b/tools/libxl/libxl_qmp.c index b09bf13..ac10f20 100644 --- a/tools/libxl/libxl_qmp.c +++ b/tools/libxl/libxl_qmp.c @@ -658,7 +658,6 @@ static void qmp_parameters_add_string(libxl__gc *gc, qmp_parameters_common_add(gc, param, name, obj); } -#if 0 static void qmp_parameters_add_bool(libxl__gc *gc, libxl__json_object **param, const char *name, bool b) @@ -669,7 +668,6 @@ static void qmp_parameters_add_bool(libxl__gc *gc, obj->u.b = b; qmp_parameters_common_add(gc, param, name, obj); } -#endif #define QMP_PARAMETERS_SPRINTF(args, name, format, ...) \ qmp_parameters_add_string(gc, args, name, \ @@ -905,6 +903,16 @@ int libxl__qmp_resume(libxl__gc *gc, int domid) return qmp_run_command(gc, domid, "cont", NULL, NULL, NULL); } +int libxl__qmp_set_global_dirty_log(libxl__gc *gc, int domid, bool enable) +{ + libxl__json_object *args = NULL; + + qmp_parameters_add_bool(gc, &args, "enable", enable); + + return qmp_run_command(gc, domid, "xen-set-global-dirty-log", args, + NULL, NULL); +} + int libxl__qmp_initializations(libxl__gc *gc, uint32_t domid, const libxl_domain_config *guest_config) { -- 1.7.4.1
Alex Bligh
2013-Feb-19 13:15 UTC
[PATCHv4 09/11] libxl_dom: Call the right switch logdirty for the right DM.
This patch dispatch the switch logdirty call depending on which device model version is running. The call to qemu-xen right now is synchronous, not like the one to qemu-xen-traditional. Backport of xen-unstable patch: : HG changeset patch : User Anthony PERARD <anthony.perard@citrix.com> : Date 1349693136 -3600 : Node ID 08fac5c2bf3dcbc493ce45091383f6ce1938f369 : Parent d4aec9eff7e6d15c2805957af620c82555553b3e Acked-by: Ian Jackson <ian.jackson@eu.citrix.com> Signed-off-by: Alex Bligh <alex@alex.org.uk> --- tools/libxl/libxl_dom.c | 45 ++++++++++++++++++++++++++++++++++++++++++--- 1 files changed, 42 insertions(+), 3 deletions(-) diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c index e1de832..95da18e 100644 --- a/tools/libxl/libxl_dom.c +++ b/tools/libxl/libxl_dom.c @@ -685,10 +685,10 @@ static void logdirty_init(libxl__logdirty_switch *lds) libxl__ev_time_init(&lds->timeout); } -void libxl__domain_suspend_common_switch_qemu_logdirty - (int domid, unsigned enable, void *user) +static void domain_suspend_switch_qemu_xen_traditional_logdirty + (int domid, unsigned enable, + libxl__save_helper_state *shs) { - libxl__save_helper_state *shs = user; libxl__egc *egc = shs->egc; libxl__domain_suspend_state *dss = CONTAINER_OF(shs, *dss, shs); libxl__logdirty_switch *lds = &dss->logdirty; @@ -756,6 +756,45 @@ void libxl__domain_suspend_common_switch_qemu_logdirty switch_logdirty_done(egc,dss,-1); } +static void domain_suspend_switch_qemu_xen_logdirty + (int domid, unsigned enable, + libxl__save_helper_state *shs) +{ + libxl__egc *egc = shs->egc; + libxl__domain_suspend_state *dss = CONTAINER_OF(shs, *dss, shs); + STATE_AO_GC(dss->ao); + int rc; + + rc = libxl__qmp_set_global_dirty_log(gc, domid, enable); + if (!rc) { + libxl__xc_domain_saverestore_async_callback_done(egc, shs, 0); + } else { + LOG(ERROR,"logdirty switch failed (rc=%d), aborting suspend",rc); + libxl__xc_domain_saverestore_async_callback_done(egc, shs, -1); + } +} + +void libxl__domain_suspend_common_switch_qemu_logdirty + (int domid, unsigned enable, void *user) +{ + libxl__save_helper_state *shs = user; + libxl__egc *egc = shs->egc; + libxl__domain_suspend_state *dss = CONTAINER_OF(shs, *dss, shs); + STATE_AO_GC(dss->ao); + + switch (libxl__device_model_version_running(gc, domid)) { + case LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN_TRADITIONAL: + domain_suspend_switch_qemu_xen_traditional_logdirty(domid, enable, shs); + break; + case LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN: + domain_suspend_switch_qemu_xen_logdirty(domid, enable, shs); + break; + default: + LOG(ERROR,"logdirty switch failed" + ", no valid device model version found, aborting suspend"); + libxl__xc_domain_saverestore_async_callback_done(egc, shs, -1); + } +} static void switch_logdirty_timeout(libxl__egc *egc, libxl__ev_time *ev, const struct timeval *requested_abs) { -- 1.7.4.1
Alex Bligh
2013-Feb-19 13:15 UTC
[PATCHv4 10/11] libxl: libxl__qmp_save: Add filename as JSON parameter to xen-save-devices-state
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com> To: xen-devel <xen-devel@lists.xen.org>, Stefano Stabellini <stefano.stabellini@eu.citrix.com> Cc: Ian Campbell <Ian.Campbell@citrix.com>, Alex Bligh <alex@alex.org.uk> Signed-off-by: Alex Bligh <alex@alex.org.uk> Acked-by: Ian Jackson <ian.jackson@eu.citrix.com> --- tools/libxl/libxl_qmp.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/tools/libxl/libxl_qmp.c b/tools/libxl/libxl_qmp.c index ac10f20..b4cc247 100644 --- a/tools/libxl/libxl_qmp.c +++ b/tools/libxl/libxl_qmp.c @@ -871,6 +871,7 @@ int libxl__qmp_save(libxl__gc *gc, int domid, const char *filename) { libxl__json_object *args = NULL; + qmp_parameters_add_string(gc, &args, "filename", (char *)filename); return qmp_run_command(gc, domid, "xen-save-devices-state", args, NULL, NULL); } -- 1.7.4.1
Backport of xen-unstable patch: : HG changeset patch : User Anthony PERARD <anthony.perard@citrix.com> : Date 1349693136 -3600 : Node ID 0995890022391682a2499a202c3c8608e1d3780a : Parent 08fac5c2bf3dcbc493ce45091383f6ce1938f369 Acked-by: Ian Jackson <ian.jackson@eu.citrix.com> Signed-off-by: Alex Bligh <alex@alex.org.uk> --- tools/libxl/libxl.c | 17 ----------------- 1 files changed, 0 insertions(+), 17 deletions(-) diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c index 4b4c5b0..9b14364 100644 --- a/tools/libxl/libxl.c +++ b/tools/libxl/libxl.c @@ -768,23 +768,6 @@ int libxl_domain_suspend(libxl_ctx *ctx, uint32_t domid, int fd, int flags, goto out_err; } - if (type == LIBXL_DOMAIN_TYPE_HVM && flags & LIBXL_SUSPEND_LIVE) { - switch (libxl__device_model_version_running(gc, domid)) { - case LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN: - LOG(ERROR, - "cannot live migrate HVM domains with qemu-xen device-model"); - rc = ERROR_FAIL; - goto out_err; - case LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN_TRADITIONAL: - /* No problem */ - break; - case -1: - rc = ERROR_FAIL; - goto out_err; - default: abort(); - } - } - libxl__domain_suspend_state *dss; GCNEW(dss); -- 1.7.4.1
Ian Jackson
2013-Feb-19 13:29 UTC
Re: [PATCHv4 00/11] libxl: Enabling live-migrate on HVM on qemu-xen device model in 4.2 - libxl patchset
Alex Bligh writes ("[PATCHv4 00/11] libxl: Enabling live-migrate on HVM on qemu-xen device model in 4.2 - libxl patchset"):> This patch series consists of 2 parts: > * 11 patches to libxl > * 5 patches to QEMU > > The 11 patches to libxl are unchanged since version 3 of the patch, > but have Acked-By lines reintroduced.Thanks for this! You''ve made this very convenient. Jan, I intend to shovel this lot into 4.2 this afternoon, unless you object. Thanks, Ian.
Jan Beulich
2013-Feb-19 13:36 UTC
Re: [PATCHv4 00/11] libxl: Enabling live-migrate on HVM on qemu-xen device model in 4.2 - libxl patchset
>>> On 19.02.13 at 14:29, Ian Jackson <Ian.Jackson@eu.citrix.com> wrote: > Alex Bligh writes ("[PATCHv4 00/11] libxl: Enabling live-migrate on HVM on > qemu-xen device model in 4.2 - libxl patchset"): >> This patch series consists of 2 parts: >> * 11 patches to libxl >> * 5 patches to QEMU >> >> The 11 patches to libxl are unchanged since version 3 of the patch, >> but have Acked-By lines reintroduced. > > Thanks for this! You''ve made this very convenient. > > Jan, I intend to shovel this lot into 4.2 this afternoon, unless you > object.Fine with me. Jan
Alex Bligh
2013-Feb-19 14:44 UTC
Re: [PATCHv4 00/11] libxl: Enabling live-migrate on HVM on qemu-xen device model in 4.2 - libxl patchset
Ian, --On 19 February 2013 13:29:01 +0000 Ian Jackson <Ian.Jackson@eu.citrix.com> wrote:>> The 11 patches to libxl are unchanged since version 3 of the patch, >> but have Acked-By lines reintroduced. > > Thanks for this! You''ve made this very convenient.No problem.> Jan, I intend to shovel this lot into 4.2 this afternoon, unless you > object.Note you will (obviously) need to change the commit ref for qemu once the qemu patches are applied. -- Alex Bligh
Ian Jackson
2013-Feb-19 15:52 UTC
Re: [PATCHv4 00/11] libxl: Enabling live-migrate on HVM on qemu-xen device model in 4.2 - libxl patchset
Alex Bligh writes ("Re: [PATCHv4 00/11] libxl: Enabling live-migrate on HVM on qemu-xen device model in 4.2 - libxl patchset"):> --On 19 February 2013 13:29:01 +0000 Ian Jackson > <Ian.Jackson@eu.citrix.com> wrote: > >> The 11 patches to libxl are unchanged since version 3 of the patch, > >> but have Acked-By lines reintroduced. > > > > Thanks for this! You''ve made this very convenient. > > No problem. > > > Jan, I intend to shovel this lot into 4.2 this afternoon, unless you > > object.Now done.> Note you will (obviously) need to change the commit ref for qemu once > the qemu patches are applied.Yes, this is a routine part of our process for updating the qemu trees. I think Stefano will be looking at your qemu-upstream-4.2 patches soon. Ian.