From: Bruno Alvisio <bruno.alvisio@gmail.com>
To: xen-devel@lists.xen.org, wei.liu2@citrix.com, dave@recoil.org,
ian.jackson@eu.citrix.com
Subject: [PATCH RFC v3 RESEND 02/12] Migration with Local Disks Mirroring: Added QMP commands used for mirroring disks
Date: Sat, 23 Dec 2017 14:03:26 +0000 [thread overview]
Message-ID: <1514037816-40864-3-git-send-email-bruno.alvisio@gmail.com> (raw)
In-Reply-To: <1514037816-40864-1-git-send-email-bruno.alvisio@gmail.com>
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@gmail.com>
---
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@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
next prev parent reply other threads:[~2017-12-23 14:03 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-12-23 14:03 [PATCH RFC v3 RESEND 00/12] Migration with Local Disks Mirroring Bruno Alvisio
2017-12-23 14:03 ` [PATCH RFC v3 RESEND 01/12] Migration with Local Disks Mirroring: Added support in libxl to handle QMP events Bruno Alvisio
2017-12-23 14:03 ` Bruno Alvisio [this message]
2017-12-23 14:03 ` [PATCH RFC v3 RESEND 03/12] Migration with Local Disks Mirroring: Refactored migrate_read_fixedmessage Bruno Alvisio
2017-12-23 14:03 ` [PATCH RFC v3 RESEND 04/12] Migration with Local Disks Mirroring: Added a new '-q' flag to xl migrate for disk mirorring Bruno Alvisio
2017-12-23 14:03 ` [PATCH RFC v3 RESEND 05/12] Migration with Local Disks Mirroring: QEMU process is started with '-incoming defer' option Bruno Alvisio
2017-12-23 14:03 ` [PATCH RFC v3 RESEND 06/12] Migration with Local Disks Mirroring: Added 'mirror_disks' field to domain_create_state Bruno Alvisio
2017-12-23 14:03 ` [PATCH RFC v3 RESEND 07/12] Migration with Local Disks Mirroring: Added new libxl_read_stream and callbacks in restore flow Bruno Alvisio
2017-12-23 14:03 ` [PATCH RFC v3 RESEND 08/12] Migration with Local Disks Mirroring: New stream phase type for libxl streams Bruno Alvisio
2017-12-23 14:03 ` [PATCH RFC v3 RESEND 09/12] Migration with Local Disks Mirroring: New stream phase type for libxc streams Bruno Alvisio
2017-12-23 14:03 ` [PATCH RFC v3 RESEND 10/12] Migration with Local Disks Mirroring: libxl save flow support Bruno Alvisio
2017-12-23 14:03 ` [PATCH RFC v3 RESEND 11/12] Migration with Local Disks Mirroring: libxl write stream support for stream phase type Bruno Alvisio
2017-12-23 14:03 ` [PATCH RFC v3 RESEND 12/12] Migration with Local Disks Mirroring: Introduce pre_mirror_disks_stream_phase op to xc_sr_save_ops Bruno Alvisio
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1514037816-40864-3-git-send-email-bruno.alvisio@gmail.com \
--to=bruno.alvisio@gmail.com \
--cc=dave@recoil.org \
--cc=ian.jackson@eu.citrix.com \
--cc=wei.liu2@citrix.com \
--cc=xen-devel@lists.xen.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).