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

[Xen-changelog] [xen-unstable] merge



# HG changeset patch
# User Tim Deegan <tim@xxxxxxx>
# Date 1322763351 0
# Node ID 2618a5d6313d3c7defbf8f60d43d148595b934e0
# Parent  a8f5faa127c4ab1cdb54fcbba23165fa5d0c2318
# Parent  b776fcd4a15c29f9e93bf6ebb037d90c5e92644b
merge
---


diff -r a8f5faa127c4 -r 2618a5d6313d Config.mk
--- a/Config.mk Thu Dec 01 18:14:24 2011 +0000
+++ b/Config.mk Thu Dec 01 18:15:51 2011 +0000
@@ -208,9 +208,9 @@
 # CONFIG_QEMU ?= `pwd`/$(XEN_ROOT)/../qemu-xen.git
 CONFIG_QEMU ?= $(QEMU_REMOTE)
 
-QEMU_TAG ?= 89daacab7035d408f32f2cb1acf68c96d6cbefed
-# Mon Nov 28 17:16:52 2011 +0000
-# qemu-dm: open char devices "file:..." with O_APPEND
+QEMU_TAG ?= 9fa2794d45ba915b42b77d4762dfa607d5587dfc
+# Thu Dec 1 17:52:39 2011 +0000
+# increase minimum timeout to 1h
 
 # Short answer -- do not enable this unless you know what you are
 # doing and are prepared for some pain.
diff -r a8f5faa127c4 -r 2618a5d6313d tools/libxl/libxl_dm.c
--- a/tools/libxl/libxl_dm.c    Thu Dec 01 18:14:24 2011 +0000
+++ b/tools/libxl/libxl_dm.c    Thu Dec 01 18:15:51 2011 +0000
@@ -408,8 +408,10 @@
         }
     }
     if (info->saved_state) {
-        flexarray_append(dm_args, "-loadvm");
-        flexarray_append(dm_args, info->saved_state);
+        /* This file descriptor is meant to be used by QEMU */
+        int migration_fd = open(info->saved_state, O_RDONLY);
+        flexarray_append(dm_args, "-incoming");
+        flexarray_append(dm_args, libxl__sprintf(gc, "fd:%d", migration_fd));
     }
     for (i = 0; info->extra && info->extra[i] != NULL; i++)
         flexarray_append(dm_args, info->extra[i]);
diff -r a8f5faa127c4 -r 2618a5d6313d tools/libxl/libxl_dom.c
--- a/tools/libxl/libxl_dom.c   Thu Dec 01 18:14:24 2011 +0000
+++ b/tools/libxl/libxl_dom.c   Thu Dec 01 18:15:51 2011 +0000
@@ -613,9 +613,31 @@
     struct stat st;
     uint32_t qemu_state_len;
 
-    LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, "Saving device model state to %s", 
filename);
-    libxl__xs_write(gc, XBT_NULL, libxl__sprintf(gc, 
"/local/domain/0/device-model/%d/command", domid), "save");
-    libxl__wait_for_device_model(gc, domid, "paused", NULL, NULL, NULL);
+    switch (libxl__device_model_version_running(gc, domid)) {
+    case LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN_TRADITIONAL: {
+        char *path = NULL;
+        LIBXL__LOG(ctx, LIBXL__LOG_DEBUG,
+                   "Saving device model state to %s", filename);
+        path = libxl__sprintf(gc, "/local/domain/0/device-model/%d/command",
+                              domid);
+        libxl__xs_write(gc, XBT_NULL, path, "save");
+        libxl__wait_for_device_model(gc, domid, "paused", NULL, NULL, NULL);
+        break;
+    }
+    case LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN:
+        fd2 = open(filename, O_WRONLY | O_CREAT | O_TRUNC);
+        if (fd2 < 0) {
+            LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR,
+                             "Unable to create a QEMU save file\n");
+            return ERROR_FAIL;
+        }
+        /* Save DM state into fd2 */
+        if (libxl__qmp_migrate(gc, domid, fd2))
+            return ERROR_FAIL;
+        break;
+    default:
+        return ERROR_INVAL;
+    }
 
     if (stat(filename, &st) < 0)
     {
diff -r a8f5faa127c4 -r 2618a5d6313d tools/libxl/libxl_internal.h
--- a/tools/libxl/libxl_internal.h      Thu Dec 01 18:14:24 2011 +0000
+++ b/tools/libxl/libxl_internal.h      Thu Dec 01 18:15:51 2011 +0000
@@ -527,6 +527,8 @@
 _hidden int libxl__qmp_pci_add(libxl__gc *gc, int d, libxl_device_pci *pcidev);
 _hidden int libxl__qmp_pci_del(libxl__gc *gc, int domid,
                                libxl_device_pci *pcidev);
+/* Save current QEMU state into fd. */
+_hidden int libxl__qmp_migrate(libxl__gc *gc, int domid, int fd);
 /* 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 -r a8f5faa127c4 -r 2618a5d6313d tools/libxl/libxl_qmp.c
--- a/tools/libxl/libxl_qmp.c   Thu Dec 01 18:14:24 2011 +0000
+++ b/tools/libxl/libxl_qmp.c   Thu Dec 01 18:15:51 2011 +0000
@@ -446,13 +446,14 @@
     return rc;
 }
 
-static int qmp_send(libxl__qmp_handler *qmp,
-                    const char *cmd, libxl_key_value_list *args,
-                    qmp_callback_t callback, void *opaque,
-                    qmp_request_context *context)
+static char *qmp_send_prepare(libxl__gc *gc, libxl__qmp_handler *qmp,
+                              const char *cmd, libxl_key_value_list *args,
+                              qmp_callback_t callback, void *opaque,
+                              qmp_request_context *context)
 {
     yajl_gen_config conf = { 0, NULL };
-    const unsigned char *buf;
+    const unsigned char *buf = NULL;
+    char *ret = NULL;
     unsigned int len = 0;
     yajl_gen_status s;
     yajl_gen hand;
@@ -460,7 +461,7 @@
 
     hand = yajl_gen_alloc(&conf, NULL);
     if (!hand) {
-        return -1;
+        return NULL;
     }
 
     yajl_gen_map_open(hand);
@@ -479,14 +480,14 @@
     if (s) {
         LIBXL__LOG(qmp->ctx, LIBXL__LOG_ERROR,
                    "Failed to generate a qmp command");
-        return -1;
+        goto out;
     }
 
     elm = malloc(sizeof (callback_id_pair));
     if (elm == NULL) {
         LIBXL__LOG_ERRNO(qmp->ctx, LIBXL__LOG_ERROR,
                          "Failed to allocate a QMP callback");
-        goto error;
+        goto out;
     }
     elm->id = qmp->last_id_used;
     elm->callback = callback;
@@ -494,22 +495,87 @@
     elm->context = context;
     SIMPLEQ_INSERT_TAIL(&qmp->callback_list, elm, next);
 
+    ret = libxl__strndup(gc, (const char*)buf, len);
+
     LIBXL__LOG(qmp->ctx, LIBXL__LOG_DEBUG, "next qmp command: '%s'", buf);
 
-    if (libxl_write_exactly(qmp->ctx, qmp->qmp_fd, buf, len,
+out:
+    yajl_gen_free(hand);
+    return ret;
+}
+
+static int qmp_send(libxl__qmp_handler *qmp,
+                    const char *cmd, libxl_key_value_list *args,
+                    qmp_callback_t callback, void *opaque,
+                    qmp_request_context *context)
+{
+    char *buf = NULL;
+    int rc = -1;
+    libxl__gc gc = LIBXL_INIT_GC(qmp->ctx);
+
+    buf = qmp_send_prepare(&gc, qmp, cmd, args, callback, opaque, context);
+
+    if (buf == NULL) {
+        goto out;
+    }
+
+    if (libxl_write_exactly(qmp->ctx, qmp->qmp_fd, buf, strlen(buf),
                             "QMP command", "QMP socket"))
-        goto error;
+        goto out;
     if (libxl_write_exactly(qmp->ctx, qmp->qmp_fd, "\r\n", 2,
                             "CRLF", "QMP socket"))
-        goto error;
+        goto out;
 
-    yajl_gen_free(hand);
+    rc = qmp->last_id_used;
+out:
+    libxl__free_all(&gc);
+    return rc;
+}
+
+static int qmp_send_fd(libxl__gc *gc, libxl__qmp_handler *qmp,
+                       libxl_key_value_list *args,
+                       qmp_callback_t callback, void *opaque,
+                       qmp_request_context *context,
+                       int fd)
+{
+    struct msghdr msg = { 0 };
+    struct cmsghdr *cmsg;
+    char control[CMSG_SPACE(sizeof (fd))];
+    struct iovec iov;
+    char *buf = NULL;
+
+    buf = qmp_send_prepare(gc, qmp, "getfd", args, callback, opaque, context);
+
+    /* Response data */
+    iov.iov_base = buf;
+    iov.iov_len  = strlen(buf);
+
+    /* compose the message */
+    msg.msg_iov = &iov;
+    msg.msg_iovlen = 1;
+    msg.msg_control = control;
+    msg.msg_controllen = sizeof (control);
+
+    /* attach open fd */
+    cmsg = CMSG_FIRSTHDR(&msg);
+    cmsg->cmsg_level = SOL_SOCKET;
+    cmsg->cmsg_type = SCM_RIGHTS;
+    cmsg->cmsg_len = CMSG_LEN(sizeof (fd));
+    *(int *)CMSG_DATA(cmsg) = fd;
+
+    msg.msg_controllen = cmsg->cmsg_len;
+
+    if (sendmsg(qmp->qmp_fd, &msg, 0) < 0) {
+        LIBXL__LOG_ERRNO(qmp->ctx, LIBXL__LOG_ERROR,
+                         "Failed to send a QMP message to QEMU.");
+        return ERROR_FAIL;
+    }
+    if (libxl_write_exactly(qmp->ctx, qmp->qmp_fd, "\r\n", 2,
+                            "CRLF", "QMP socket")) {
+        return ERROR_FAIL;
+    }
 
     return qmp->last_id_used;
-
-error:
-    yajl_gen_free(hand);
-    return -1;
 }
 
 static int qmp_synchronous_send(libxl__qmp_handler *qmp, const char *cmd,
@@ -748,6 +814,69 @@
     return qmp_device_del(gc, domid, id);
 }
 
+static int qmp_getfd(libxl__gc *gc, libxl__qmp_handler *qmp,
+                     int fd, const char *name)
+{
+    flexarray_t *parameters = NULL;
+    libxl_key_value_list args = NULL;
+    int rc = 0;
+
+    parameters = flexarray_make(2, 1);
+    if (!parameters)
+        return ERROR_NOMEM;
+    flexarray_append_pair(parameters, "fdname", (char*)name);
+    args = libxl__xs_kvs_of_flexarray(gc, parameters, parameters->count);
+    if (!args) {
+        rc = ERROR_NOMEM;
+        goto out;
+    }
+
+    if (qmp_send_fd(gc, qmp, &args, NULL, NULL, NULL, fd) < 0) {
+        rc = ERROR_FAIL;
+    }
+out:
+    flexarray_free(parameters);
+    return rc;
+}
+
+int libxl__qmp_migrate(libxl__gc *gc, int domid, int fd)
+{
+#define MIGRATE_FD_NAME "dm-migrate"
+    libxl__qmp_handler *qmp = NULL;
+    flexarray_t *parameters = NULL;
+    libxl_key_value_list args = NULL;
+    int rc = 0;
+
+    qmp = libxl__qmp_initialize(libxl__gc_owner(gc), domid);
+    if (!qmp)
+        return ERROR_FAIL;
+
+    rc = qmp_getfd(gc, qmp, fd, MIGRATE_FD_NAME);
+    if (rc)
+        goto out;
+
+    parameters = flexarray_make(2, 1);
+    if (!parameters) {
+        rc = ERROR_NOMEM;
+        goto out;
+    }
+    flexarray_append_pair(parameters, "uri", "fd:" MIGRATE_FD_NAME);
+    args = libxl__xs_kvs_of_flexarray(gc, parameters, parameters->count);
+    if (!args) {
+        rc = ERROR_NOMEM;
+        goto out2;
+    }
+
+    rc = qmp_synchronous_send(qmp, "migrate", &args,
+                              NULL, NULL, qmp->timeout);
+
+out2:
+    flexarray_free(parameters);
+out:
+    libxl__qmp_close(qmp);
+    return rc;
+}
+
 int libxl__qmp_initializations(libxl_ctx *ctx, uint32_t domid)
 {
     libxl__qmp_handler *qmp = NULL;

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

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