[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |