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

[Xen-devel] [PATCH RFC v3 04/12] Migration with Local Disks Mirroring: Added a new '-q' flag to xl migrate for disk mirorring



When the '-q' flag is provided to the 'xl migrate' command all the block devices
that are local should be mirrored to the destination node. If the flag is not
present migration flow will be equivalent to current migration flow. A new
'mirror_disks' field is added to the xl domain_create struct to indicate that
disks will be mirrored during instance startup. A new LIBXL_SUSPEND_MIRROR_DISK
flag is added to indicate that the block mirror jobs should be performed during
the suspension of the instance. libxl_domain_suspend takes a new 'hostname'
param with the name of the host where the QEMU drives will be mirrored to.
libxl_domain_suspend takes a 'recv_fd' param that is used for receving messages
from destination during migration.

Signed-off-by: Bruno Alvisio <bruno.alvisio@xxxxxxxxx>
---
 tools/libxl/libxl.h                  |  4 +-
 tools/libxl/libxl_domain.c           |  4 +-
 tools/ocaml/libs/xl/xenlight_stubs.c |  2 +-
 tools/xl/xl.h                        |  1 +
 tools/xl/xl_cmdtable.c               |  3 +-
 tools/xl/xl_migrate.c                | 74 +++++++++++++++++++++++++++++++-----
 tools/xl/xl_saverestore.c            |  2 +-
 7 files changed, 75 insertions(+), 15 deletions(-)

diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
index 5e9aed7..7828ba8 100644
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -1444,12 +1444,14 @@ int libxl_retrieve_domain_configuration(libxl_ctx *ctx, 
uint32_t domid,
                                         libxl_domain_config *d_config)
                                         LIBXL_EXTERNAL_CALLERS_ONLY;
 
-int libxl_domain_suspend(libxl_ctx *ctx, uint32_t domid, int fd,
+int libxl_domain_suspend(libxl_ctx *ctx, uint32_t domid, int fd, int recv_fd,
                          int flags, /* LIBXL_SUSPEND_* */
+                         const char* hostname,
                          const libxl_asyncop_how *ao_how)
                          LIBXL_EXTERNAL_CALLERS_ONLY;
 #define LIBXL_SUSPEND_DEBUG 1
 #define LIBXL_SUSPEND_LIVE 2
+#define LIBXL_SUSPEND_MIRROR_DISKS 4
 
 /* @param suspend_cancel [from xenctrl.h:xc_domain_resume( @param fast )]
  *   If this parameter is true, use co-operative resume. The guest
diff --git a/tools/libxl/libxl_domain.c b/tools/libxl/libxl_domain.c
index 814f812..d1209cd 100644
--- a/tools/libxl/libxl_domain.c
+++ b/tools/libxl/libxl_domain.c
@@ -486,7 +486,8 @@ static void domain_suspend_cb(libxl__egc *egc,
 
 }
 
-int libxl_domain_suspend(libxl_ctx *ctx, uint32_t domid, int fd, int flags,
+int libxl_domain_suspend(libxl_ctx *ctx, uint32_t domid, int fd, int recv_fd,
+                         int flags, const char* hostname,
                          const libxl_asyncop_how *ao_how)
 {
     AO_CREATE(ctx, domid, ao_how);
@@ -506,6 +507,7 @@ int libxl_domain_suspend(libxl_ctx *ctx, uint32_t domid, 
int fd, int flags,
 
     dss->domid = domid;
     dss->fd = fd;
+    dss->recv_fd = recv_fd;
     dss->type = type;
     dss->live = flags & LIBXL_SUSPEND_LIVE;
     dss->debug = flags & LIBXL_SUSPEND_DEBUG;
diff --git a/tools/ocaml/libs/xl/xenlight_stubs.c 
b/tools/ocaml/libs/xl/xenlight_stubs.c
index 0140780..a757782 100644
--- a/tools/ocaml/libs/xl/xenlight_stubs.c
+++ b/tools/ocaml/libs/xl/xenlight_stubs.c
@@ -611,7 +611,7 @@ value stub_libxl_domain_suspend(value ctx, value domid, 
value fd, value async, v
        libxl_asyncop_how *ao_how = aohow_val(async);
 
        caml_enter_blocking_section();
-       ret = libxl_domain_suspend(CTX, c_domid, c_fd, 0, ao_how);
+       ret = libxl_domain_suspend(CTX, c_domid, c_fd, 0, 0, NULL, ao_how);
        caml_leave_blocking_section();
 
        free(ao_how);
diff --git a/tools/xl/xl.h b/tools/xl/xl.h
index 6b60d1d..fd8e8e6 100644
--- a/tools/xl/xl.h
+++ b/tools/xl/xl.h
@@ -35,6 +35,7 @@ struct domain_create {
     int daemonize;
     int monitor; /* handle guest reboots etc */
     int paused;
+    int mirror_disks;
     int dryrun;
     int quiet;
     int vnc;
diff --git a/tools/xl/xl_cmdtable.c b/tools/xl/xl_cmdtable.c
index 5546cf6..45a0b1a 100644
--- a/tools/xl/xl_cmdtable.c
+++ b/tools/xl/xl_cmdtable.c
@@ -165,7 +165,8 @@ struct cmd_spec cmd_table[] = {
       "-e              Do not wait in the background (on <host>) for the 
death\n"
       "                of the domain.\n"
       "--debug         Print huge (!) amount of debug during the migration 
process.\n"
-      "-p              Do not unpause domain after migrating it."
+      "-p              Do not unpause domain after migrating it.\n"
+      "-q              Mirror local disks to destination - Copy all local 
storage devices."
     },
     { "restore",
       &main_restore, 0, 1,
diff --git a/tools/xl/xl_migrate.c b/tools/xl/xl_migrate.c
index 33d39e8..48b0179 100644
--- a/tools/xl/xl_migrate.c
+++ b/tools/xl/xl_migrate.c
@@ -157,7 +157,8 @@ static void migrate_do_preamble(int send_fd, int recv_fd, 
pid_t child,
 }
 
 static void migrate_domain(uint32_t domid, const char *rune, int debug,
-                           const char *override_config_file)
+                           const char *override_config_file,
+                           int mirror_disks, const char* hostname)
 {
     pid_t child = -1;
     int rc;
@@ -185,7 +186,10 @@ static void migrate_domain(uint32_t domid, const char 
*rune, int debug,
 
     if (debug)
         flags |= LIBXL_SUSPEND_DEBUG;
-    rc = libxl_domain_suspend(ctx, domid, send_fd, flags, NULL);
+    if (mirror_disks)
+        flags |= LIBXL_SUSPEND_MIRROR_DISKS;
+    rc = libxl_domain_suspend(ctx, domid, send_fd, recv_fd, flags, hostname,
+                              NULL);
     if (rc) {
         fprintf(stderr, "migration sender: libxl_domain_suspend failed"
                 " (rc=%d)\n", rc);
@@ -296,7 +300,7 @@ static void migrate_domain(uint32_t domid, const char 
*rune, int debug,
 }
 
 static void migrate_receive(int debug, int daemonize, int monitor,
-                            int pause_after_migration,
+                            int pause_after_migration, int mirror_disks,
                             int send_fd, int recv_fd,
                             libxl_checkpointed_stream checkpointed,
                             char *colo_proxy_script,
@@ -323,6 +327,7 @@ static void migrate_receive(int debug, int daemonize, int 
monitor,
     dom_info.daemonize = daemonize;
     dom_info.monitor = monitor;
     dom_info.paused = 1;
+    dom_info.mirror_disks = mirror_disks;
     dom_info.migrate_fd = recv_fd;
     dom_info.send_back_fd = send_fd;
     dom_info.migration_domname_r = &migration_domname;
@@ -458,6 +463,7 @@ static void migrate_receive(int debug, int daemonize, int 
monitor,
 int main_migrate_receive(int argc, char **argv)
 {
     int debug = 0, daemonize = 1, monitor = 1, pause_after_migration = 0;
+    int mirror_disks = 0;
     libxl_checkpointed_stream checkpointed = LIBXL_CHECKPOINTED_STREAM_NONE;
     int opt;
     bool userspace_colo_proxy = false;
@@ -470,7 +476,7 @@ int main_migrate_receive(int argc, char **argv)
         COMMON_LONG_OPTS
     };
 
-    SWITCH_FOREACH_OPT(opt, "Fedrp", opts, "migrate-receive", 0) {
+    SWITCH_FOREACH_OPT(opt, "Fedrpq", opts, "migrate-receive", 0) {
     case 'F':
         daemonize = 0;
         break;
@@ -496,6 +502,9 @@ int main_migrate_receive(int argc, char **argv)
     case 'p':
         pause_after_migration = 1;
         break;
+    case 'q':
+        mirror_disks = 1;
+        break;
     }
 
     if (argc-optind != 0) {
@@ -503,7 +512,7 @@ int main_migrate_receive(int argc, char **argv)
         return EXIT_FAILURE;
     }
     migrate_receive(debug, daemonize, monitor, pause_after_migration,
-                    STDOUT_FILENO, STDIN_FILENO,
+                    mirror_disks, STDOUT_FILENO, STDIN_FILENO,
                     checkpointed, script, userspace_colo_proxy);
 
     return EXIT_SUCCESS;
@@ -512,18 +521,22 @@ int main_migrate_receive(int argc, char **argv)
 int main_migrate(int argc, char **argv)
 {
     uint32_t domid;
+    libxl_domain_config d_config;
     const char *config_filename = NULL;
     const char *ssh_command = "ssh";
     char *rune = NULL;
     char *host;
-    int opt, daemonize = 1, monitor = 1, debug = 0, pause_after_migration = 0;
+    char *hostname;
+    int opt, daemonize = 1, monitor = 1, debug = 0, pause_after_migration = 0,
+    mirror_disks = 0;
+    int rc;
     static struct option opts[] = {
         {"debug", 0, 0, 0x100},
         {"live", 0, 0, 0x200},
         COMMON_LONG_OPTS
     };
 
-    SWITCH_FOREACH_OPT(opt, "FC:s:ep", opts, "migrate", 2) {
+    SWITCH_FOREACH_OPT(opt, "FC:s:epq", opts, "migrate", 2) {
     case 'C':
         config_filename = optarg;
         break;
@@ -540,6 +553,9 @@ int main_migrate(int argc, char **argv)
     case 'p':
         pause_after_migration = 1;
         break;
+    case 'q':
+        mirror_disks = 1;
+        break;
     case 0x100: /* --debug */
         debug = 1;
         break;
@@ -551,6 +567,33 @@ int main_migrate(int argc, char **argv)
     domid = find_domain(argv[optind]);
     host = argv[optind + 1];
 
+    hostname = strchr(host, '@');
+    hostname++;
+
+    if (mirror_disks) {
+        libxl_domain_config_init(&d_config);
+        rc = libxl_retrieve_domain_configuration(ctx, domid, &d_config);
+        if (rc) {
+            fprintf(stderr, "unable to retrieve domain configuration\n");
+            goto failed_config;
+        }
+        libxl_domain_build_info b_info = d_config.b_info;
+        libxl_device_model_version model_version = b_info.device_model_version;
+        libxl_domain_type type = b_info.type;
+
+        if (model_version != LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN)
+            goto failed_mirror;
+
+        if (type != LIBXL_DOMAIN_TYPE_HVM) {
+            goto failed_mirror;
+        } else {
+            libxl_defbool_setdefault(&b_info.u.hvm.xen_platform_pci, true);
+            if (libxl_defbool_val(b_info.u.hvm.xen_platform_pci))
+                goto failed_mirror;
+        }
+        libxl_domain_config_dispose(&d_config);
+    }
+
     bool pass_tty_arg = progress_use_cr || (isatty(2) > 0);
 
     if (!ssh_command[0]) {
@@ -567,17 +610,28 @@ int main_migrate(int argc, char **argv)
         } else {
             verbose_len = (minmsglevel_default - minmsglevel) + 2;
         }
-        xasprintf(&rune, "exec %s %s xl%s%.*s migrate-receive%s%s%s",
+        xasprintf(&rune, "exec %s %s xl%s%.*s migrate-receive%s%s%s%s",
                   ssh_command, host,
                   pass_tty_arg ? " -t" : "",
                   verbose_len, verbose_buf,
                   daemonize ? "" : " -e",
                   debug ? " -d" : "",
-                  pause_after_migration ? " -p" : "");
+                  pause_after_migration ? " -p" : "",
+                  mirror_disks ? " -q" : "");
     }
 
-    migrate_domain(domid, rune, debug, config_filename);
+    migrate_domain(domid, rune, debug, config_filename, mirror_disks,
+                   hostname);
     return EXIT_SUCCESS;
+
+ failed_mirror:
+    fprintf(stderr, "Migration with local disks mirroring is only supported "
+                    "for HVM using QEMU_XEN as device model version and "
+                    "xen_platform_pci = 1\n");
+
+ failed_config:
+    libxl_domain_config_dispose(&d_config);
+    exit(EXIT_FAILURE);
 }
 
 int main_remus(int argc, char **argv)
diff --git a/tools/xl/xl_saverestore.c b/tools/xl/xl_saverestore.c
index 9afeade..9215a45 100644
--- a/tools/xl/xl_saverestore.c
+++ b/tools/xl/xl_saverestore.c
@@ -141,7 +141,7 @@ static int save_domain(uint32_t domid, const char 
*filename, int checkpoint,
 
     save_domain_core_writeconfig(fd, filename, config_data, config_len);
 
-    int rc = libxl_domain_suspend(ctx, domid, fd, 0, NULL);
+    int rc = libxl_domain_suspend(ctx, domid, fd, 0, 0, NULL, NULL);
     close(fd);
 
     if (rc < 0) {
-- 
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®.