[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH RFC v3 RESEND 10/12] Migration with Local Disks Mirroring: libxl save flow support



The domain save state contains a new 'mirror_disks' field. It determines the
flow of the domain save. If false, the save flow will invoke the DEFAULT phase
libxl/libxc stream type. If true, the save flow invokes the PRE_MIRROR_DISKS
phase stream type first. Upon reception of the signal from the source that the
NBD server has been started it triggers the disks mirroring job. Once it
receives an event from QEMU that the mirroring job is complete, the
POST_MIRROR_DISKS phase stream type is invoked.

Signed-off-by: Bruno Alvisio <bruno.alvisio@xxxxxxxxx>
---
 tools/libxl/libxl_dom_save.c | 53 ++++++++++++++++++++++++++++++++++++++++++--
 tools/libxl/libxl_domain.c   |  2 ++
 tools/libxl/libxl_internal.h |  4 ++++
 3 files changed, 57 insertions(+), 2 deletions(-)

diff --git a/tools/libxl/libxl_dom_save.c b/tools/libxl/libxl_dom_save.c
index 6487672..78c4e86 100644
--- a/tools/libxl/libxl_dom_save.c
+++ b/tools/libxl/libxl_dom_save.c
@@ -25,6 +25,9 @@ static void stream_done(libxl__egc *egc,
                         libxl__stream_write_state *sws, int rc);
 static void domain_save_done(libxl__egc *egc,
                              libxl__domain_save_state *dss, int rc);
+static void domain_pre_mirror_disks_done(libxl__egc *egc,
+                                         libxl__stream_write_state *sws,
+                                         int rc);
 
 /*----- complicated callback, called by xc_domain_save -----*/
 
@@ -411,14 +414,60 @@ void libxl__domain_save(libxl__egc *egc, 
libxl__domain_save_state *dss)
     dss->sws.fd  = dss->fd;
     dss->sws.back_channel = false;
     dss->sws.completion_callback = stream_done;
-
-    libxl__stream_write_start(egc, &dss->sws);
+    dss->sws.mirror_disks = 0;
+
+    if (!dss->mirror_disks) {
+        libxl__stream_write_start(egc, &dss->sws);
+    } else {
+        dss->sws_mirror_disks.ao  = dss->ao;
+        dss->sws_mirror_disks.dss = dss;
+        dss->sws_mirror_disks.fd  = dss->fd;
+        dss->sws_mirror_disks.back_channel = false;
+        dss->sws_mirror_disks.mirror_disks = 1;
+        dss->sws_mirror_disks.completion_callback = 
domain_pre_mirror_disks_done;
+
+        libxl__stream_write_start(egc, &dss->sws_mirror_disks);
+    }
     return;
 
  out:
     domain_save_done(egc, dss, rc);
 }
 
+static void domain_pre_mirror_disks_done(libxl__egc *egc,
+                                         libxl__stream_write_state *sws,
+                                         int rc)
+{
+    libxl__domain_save_state *dss = sws->dss;
+    STATE_AO_GC(dss->ao);
+    const uint32_t domid = dss->domid;
+    char* target;
+
+    if (rc)
+        goto err;
+
+    rc = libxl_read_fixedmessage(CTX, dss->recv_fd, nbd_server_started_banner,
+                                 sizeof(nbd_server_started_banner)-1,
+                                 "migration stream", 0);
+    if (rc)
+        goto err;
+
+    target = GCSPRINTF("nbd:%s:%s:exportname=%s", dss->hostname,
+                       DRIVE_MIRROR_PORT, DRIVE_MIRROR_DEVICE);
+    rc = libxl__qmp_drive_mirror(gc, dss->domid, DRIVE_MIRROR_DEVICE, target,
+                                 "raw");
+    if (rc) {
+        LOGD(ERROR, domid, "Sending QMP drive mirror command failed");
+        goto err;
+    }
+
+    libxl__stream_write_start(egc, &sws->dss->sws);
+    return;
+
+ err:
+   dss->callback(egc, dss, rc);
+}
+
 static void stream_done(libxl__egc *egc,
                         libxl__stream_write_state *sws, int rc)
 {
diff --git a/tools/libxl/libxl_domain.c b/tools/libxl/libxl_domain.c
index d1209cd..341ed52 100644
--- a/tools/libxl/libxl_domain.c
+++ b/tools/libxl/libxl_domain.c
@@ -511,6 +511,8 @@ int libxl_domain_suspend(libxl_ctx *ctx, uint32_t domid, 
int fd, int recv_fd,
     dss->type = type;
     dss->live = flags & LIBXL_SUSPEND_LIVE;
     dss->debug = flags & LIBXL_SUSPEND_DEBUG;
+    dss->mirror_disks = (flags & LIBXL_SUSPEND_MIRROR_DISKS) ? 1 : 0;
+    dss->hostname = hostname;
     dss->checkpointed_stream = LIBXL_CHECKPOINTED_STREAM_NONE;
 
     rc = libxl__fd_flags_modify_save(gc, dss->fd,
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 76bbe48..0a3215f 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -3197,6 +3197,7 @@ struct libxl__stream_write_state {
     libxl__domain_save_state *dss;
     int fd;
     bool back_channel;
+    int mirror_disks;
     void (*completion_callback)(libxl__egc *egc,
                                 libxl__stream_write_state *sws,
                                 int rc);
@@ -3296,6 +3297,8 @@ struct libxl__domain_save_state {
     libxl_domain_type type;
     int live;
     int debug;
+    int mirror_disks;
+    const char* hostname;
     int checkpointed_stream;
     const libxl_domain_remus_info *remus;
     /* private */
@@ -3311,6 +3314,7 @@ struct libxl__domain_save_state {
     };
     libxl__checkpoint_devices_state cds;
     libxl__stream_write_state sws;
+    libxl__stream_write_state sws_mirror_disks;
     libxl__logdirty_switch logdirty;
 };
 
-- 
2.3.2 (Apple Git-55)


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.