[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH RFC v3 RESEND 02/12] Migration with Local Disks Mirroring: Added QMP commands used for mirroring disks
Migration with local disks mirroring uses the embedded NBD server in QEMU. A NBD server is added in libxl during instance creation time in the destination (QMP command: nbd_server_add). The drive mirror command (QMP: driver_mirror) is executed on the source during 'instance save' to replicate the disk in the destination. When the local disk migration option is used, the QEMU process in the destination will be started with the "-incoming defer" option instead of "-incoming fd". Once the disk and memory have been transferred to the destination the QEMU process will be resumed using the migrate incoming command (QMP command: migrate_incoming). Signed-off-by: Bruno Alvisio <bruno.alvisio@xxxxxxxxx> --- tools/libxl/libxl_internal.h | 11 ++++ tools/libxl/libxl_qmp.c | 139 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 150 insertions(+) diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h index bfa95d8..4d7679e 100644 --- a/tools/libxl/libxl_internal.h +++ b/tools/libxl/libxl_internal.h @@ -1830,6 +1830,17 @@ _hidden int libxl__qmp_nbd_server_add(libxl__gc *gc, int domid, /* Start replication */ _hidden int libxl__qmp_start_replication(libxl__gc *gc, int domid, bool primary); +/* Mirror drive */ +_hidden int libxl__qmp_drive_mirror(libxl__gc *gc, int domid, + const char* device, const char* target, + const char* format); +/* Query block devices */ +_hidden int libxl__qmp_query_block(libxl__gc *gc, int domid, + char *device_names); +/* Resume QEMU process started with -incoming defer option */ +_hidden int libxl__qmp_migrate_incoming(libxl__gc *gc, int domid, + const char* uri); + /* Get replication error that occurs when the vm is running */ _hidden int libxl__qmp_query_xen_replication_status(libxl__gc *gc, int domid); /* Do checkpoint */ diff --git a/tools/libxl/libxl_qmp.c b/tools/libxl/libxl_qmp.c index 0e993af..1a1a318 100644 --- a/tools/libxl/libxl_qmp.c +++ b/tools/libxl/libxl_qmp.c @@ -1159,6 +1159,145 @@ int libxl__qmp_stop_replication(libxl__gc *gc, int domid, bool primary) return qmp_run_command(gc, domid, "xen-set-replication", args, NULL, NULL); } +static int block_job_ready_handler(libxl__qmp_handler *qmp, + const libxl__json_object *data, + void *opaque) +{ + GC_INIT(qmp->ctx); + int rc = -1; + + const char *type; + const char *device; + unsigned int len; + unsigned int offset; + unsigned int speed; + + const libxl__json_object *obj = NULL; + + obj = libxl__json_map_get("type", data, JSON_STRING); + if (!obj) { + LOGD(ERROR, qmp->domid, "Failed to retrieve job type."); + rc = ERROR_FAIL; + goto out; + } + type = libxl__json_object_get_string(obj); + + obj = libxl__json_map_get("device", data, JSON_STRING); + if (!obj) { + LOGD(ERROR, qmp->domid, "Failed to retrieve device."); + rc = ERROR_FAIL; + goto out; + } + device = libxl__json_object_get_string(obj); + + obj = libxl__json_map_get("len", data, JSON_INTEGER); + if (!obj) { + LOGD(ERROR, qmp->domid, "Failed to retrieve length."); + rc = ERROR_FAIL; + goto out; + } + len = libxl__json_object_get_integer(obj); + + obj = libxl__json_map_get("offset", data, JSON_INTEGER); + if (!obj) { + LOGD(ERROR, qmp->domid, "Failed to retrieve offset."); + rc = ERROR_FAIL; + goto out; + } + offset = libxl__json_object_get_integer(obj); + + obj = libxl__json_map_get("speed", data, JSON_INTEGER); + if (!obj) { + LOGD(ERROR, qmp->domid, "Failed to retrieve speed."); + rc = ERROR_FAIL; + goto out; + } + speed = libxl__json_object_get_integer(obj); + + LOGD(INFO, qmp->domid, "Block Job Ready: Details: Device: %s, Type: %s, " + "Len: %u, Offset: %u, Speed %u.", device, type, + len, offset, speed); + + rc = 0; +out: + GC_FREE; + return rc; +} + +int libxl__qmp_drive_mirror(libxl__gc *gc, int domid, const char* device, + const char* target, const char* format) +{ + libxl__qmp_handler *qmp = NULL; + libxl__json_object *args = NULL; + int block_job_timeout = 3600; + int rc = 0; + + qmp = libxl__qmp_initialize(gc, domid); + if (!qmp) + return -1; + + qmp_parameters_add_string(gc, &args, "device", device); + qmp_parameters_add_string(gc, &args, "target", target); + qmp_parameters_add_string(gc, &args, "sync", "full"); + qmp_parameters_add_string(gc, &args, "format", format); + qmp_parameters_add_string(gc, &args, "mode", "existing"); + qmp_parameters_add_integer(gc, &args, "granularity", 0); + qmp_parameters_add_integer(gc, &args, "buf-size", 0); + + rc = qmp_synchronous_send(qmp, "drive-mirror", args, + NULL, NULL, qmp->timeout); + + if ( !rc ) { + event_handler_pair hep = { + .event_type = "BLOCK_JOB_READY", + .event_handler = block_job_ready_handler, + }; + + rc = wait_for_event(qmp, &hep, block_job_timeout); + } + libxl__qmp_close(qmp); + return rc; +} + +static int query_block_callback(libxl__qmp_handler *qmp, + const libxl__json_object *response, + void *opaque) +{ + GC_INIT(qmp->ctx); + const libxl__json_object *blockinfo = NULL; + int i, rc = -1; + + for (i = 0; (blockinfo = libxl__json_array_get(response, i)); i++) { + const libxl__json_object *d; + const char* device_name; + d = libxl__json_map_get("device", blockinfo, JSON_STRING); + if (!d) + goto out; + + device_name = libxl__json_object_get_string(d); + } + + rc = 0; +out: + GC_FREE; + return rc; +} + +int libxl__qmp_query_block(libxl__gc *gc, int domid, char *device_names) +{ + return qmp_run_command(gc, domid, "query-block", NULL, query_block_callback, + device_names); +} + +int libxl__qmp_migrate_incoming(libxl__gc *gc, int domid, const char* uri) +{ + libxl__json_object *args = NULL; + + qmp_parameters_add_string(gc, &args, "uri", uri); + + return qmp_run_command(gc, domid, "migrate-incoming", args, NULL, NULL); +} + int libxl__qmp_nbd_server_stop(libxl__gc *gc, int domid) { return qmp_run_command(gc, domid, "nbd-server-stop", NULL, NULL, NULL); -- 2.3.2 (Apple Git-55) _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |