[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH VERY RFC 3/5] tools/libxl: Implement libxl_domain_restore() for v2 streams
TODO: * Make it asynchronous * Integrate with the json series * Support for HVM elements Signed-off-by: Ross Lagerwall <ross.lagerwall@xxxxxxxxxx> Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> --- tools/libxl/libxl.c | 13 +++ tools/libxl/libxl.h | 12 +++ tools/libxl/libxl_create.c | 234 ++++++++++++++++++++++++++++++++++++++++++ tools/libxl/libxl_internal.h | 5 + 4 files changed, 264 insertions(+) diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c index 2ae5fca..209d56a 100644 --- a/tools/libxl/libxl.c +++ b/tools/libxl/libxl.c @@ -878,6 +878,19 @@ int libxl_domain_suspend(libxl_ctx *ctx, uint32_t domid, int fd, int flags, return AO_ABORT(rc); } +/* + * Restore a domain from an fd using the LibXenLight Domain Image Format v2. + * Returns 0 on success, non-zero otherwise. + */ +int libxl_domain_restore(libxl_ctx *ctx, + libxl_domain_config *d_config, /* TMP until json is sorted */ + int restore_fd, uint32_t *domid, + const libxl_asyncop_how *ao_how, + const libxl_asyncprogress_how *aop_console_how) +{ + return libxl__domain_restore(ctx, restore_fd, domid, d_config); +} + int libxl_domain_pause(libxl_ctx *ctx, uint32_t domid) { int ret; diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h index 460207b..fb14a91 100644 --- a/tools/libxl/libxl.h +++ b/tools/libxl/libxl.h @@ -857,6 +857,18 @@ int static inline libxl_domain_create_restore_0x040200( #endif +/* Restore from a v2 stream + * + * TODO - Make this function properly asynchronous, and remove d_config + * parameter. + */ +int libxl_domain_restore(libxl_ctx *ctx, + libxl_domain_config *d_config, /* TMP until json is sorted */ + int restore_fd, uint32_t *domid, + const libxl_asyncop_how *ao_how, + const libxl_asyncprogress_how *aop_console_how) + LIBXL_EXTERNAL_CALLERS_ONLY; + /* A progress report will be made via ao_console_how, of type * domain_create_console_available, when the domain's primary * console is available and can be connected to. diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c index ee328e9..4f3a493 100644 --- a/tools/libxl/libxl_create.c +++ b/tools/libxl/libxl_create.c @@ -19,6 +19,7 @@ #include "libxl_internal.h" #include "libxl_arch.h" +#include "libxl_saverestore.h" #include <xc_dom.h> #include <xenguest.h> @@ -1487,6 +1488,239 @@ int libxl_domain_create_restore(libxl_ctx *ctx, libxl_domain_config *d_config, } /* + * Helper for stub handlers. This should go away when the stub handlers are + * implemented. + */ +static int skip_data(int fd, int len) +{ + unsigned char buf[4096]; + int ret = 0; + ssize_t n; + + while (len > 0) { + n = read(fd, buf, len < sizeof(buf) ? len : sizeof(buf)); + if (n <= 0) { + if (errno == EAGAIN) + continue; + ret = ERROR_FAIL; + goto out; + } + + len -= n; + } + +out: + return ret; +} + +/* + * Process a domain JSON string read from fd. + * Returns 0 on success, non-zero otherwise. + */ +static int restore_domain_json(libxl_ctx *ctx, int fd, uint32_t len) +{ + int ret = 0; + + ret = skip_data(fd, len); + + return ret; +} + +/* + * Process a libxc_context blob by passing it off to libxc. + * Returns 0 on success, non-zero otherwise. + */ +static int restore_libxc_context(libxl_ctx *ctx, int fd, + libxl_domain_config *d_config, uint32_t *domid) +{ + return do_domain_create(ctx, d_config, domid, fd, 0, NULL, NULL); +} + +/* + * Process a set of xenstore key-value pairs. + * Returns 0 on success, non-zero otherwise. + */ +static int restore_xenstore_data(libxl_ctx *ctx, int fd, uint32_t len) +{ + int ret = 0; + + ret = skip_data(fd, len); + + return ret; +} + +/* + * Process a qemu traditional emulator context. + * Returns 0 on success, non-zero otherwise. + */ +static int restore_qemu_traditional(libxl_ctx *ctx, int fd, uint32_t len) +{ + return 0; +} + +/* + * Process a qemu upstream emulator context. + * Returns 0 on success, non-zero otherwise. + */ +static int restore_qemu_upstream(libxl_ctx *ctx, int fd, uint32_t len) +{ + return 0; +} + +/* + * Process an emulator context record. + * Returns 0 on success, non-zero otherwise. + */ +static int restore_emulator_context(libxl_ctx *ctx, int fd, uint32_t len) +{ + struct restore_emulator_hdr hdr; + int ret = 0; + + if (libxl_read_exactly(ctx, fd, &hdr, sizeof(hdr), + "restore stream", "emulator context header")) { + ret = ERROR_FAIL; + goto out; + } + hdr.id = be32toh(hdr.id); + hdr.index = be32toh(hdr.index); + len -= sizeof(hdr); + + switch (hdr.id) { + break; + case EMULATOR_QEMU_TRADITIONAL: + LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, + "Emulator: QEMU traditional, index %u", hdr.index); + ret = restore_qemu_traditional(ctx, fd, len); + break; + case EMULATOR_QEMU_UPSTREAM: + LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, + "Emulator: QEMU upstream, index %u", hdr.index); + ret = restore_qemu_upstream(ctx, fd, len); + break; + case EMULATOR_UNKNOWN: + default: + LIBXL__LOG(ctx, LIBXL__LOG_ERROR, + "Emulator: Unknown id 0x%08x, index %u", hdr.id, hdr.index); + ret = ERROR_FAIL; + break; + } + + if (ret) + goto out; + + ret = skip_data(fd, len); + +out: + return ret; +} + +int libxl__domain_restore(libxl_ctx *ctx, int restore_fd, uint32_t *domid, + libxl_domain_config *d_config) +{ + GC_INIT(ctx); + struct restore_hdr hdr; + struct restore_rec_hdr rechdr; + int ret = 0; + + if (libxl_read_exactly(ctx, restore_fd, &hdr, sizeof(hdr), + "restore stream", "stream header")) { + ret = ERROR_FAIL; + goto out; + } + hdr.ident = be64toh(hdr.ident); + hdr.version = be32toh(hdr.version); + hdr.options = be32toh(hdr.options); + + if (hdr.ident != RESTORE_STREAM_IDENT) { + LIBXL__LOG(ctx, LIBXL__LOG_ERROR, + "Invalid ident: Got 0x%016"PRIx64, hdr.ident); + ret = ERROR_FAIL; + goto out; + } + if (hdr.version != RESTORE_STREAM_VERSION) { + LIBXL__LOG(ctx, LIBXL__LOG_ERROR, + "Invalid Version: Expected %u, Got %u", + hdr.version, RESTORE_STREAM_VERSION); + ret = ERROR_FAIL; + goto out; + } + if (hdr.options & RESTORE_OPT_BIG_ENDIAN) { + LIBXL__LOG(ctx, LIBXL__LOG_ERROR, + "Unable to handle big endian streams"); + ret = ERROR_FAIL; + goto out; + } + if (hdr.options & RESTORE_OPT_LEGACY) { + LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "Unable to restore legacy streams"); + ret = ERROR_FAIL; + goto out; + } + + do { + if (libxl_read_exactly(ctx, restore_fd, &rechdr, sizeof(rechdr), + "restore stream", "record header")) { + ret = ERROR_FAIL; + goto out; + } + + switch (rechdr.type) { + case REC_TYPE_END: + LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, + "Record: END, length %u", rechdr.length); + if (rechdr.length != 0) { + LIBXL__LOG(ctx, LIBXL__LOG_ERROR, + "Encountered END record with non-zero length"); + ret = ERROR_FAIL; + } + break; + case REC_TYPE_DOMAIN_JSON: + LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, + "Record: DOMAIN_JSON, length %u", rechdr.length); + ret = restore_domain_json(ctx, restore_fd, rechdr.length); + break; + case REC_TYPE_LIBXC_CONTEXT: + LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, + "Record: LIBXC_CONTEXT, length %u", rechdr.length); + ret = restore_libxc_context(ctx, restore_fd, d_config, domid); + break; + case REC_TYPE_XENSTORE_DATA: + LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, + "Record: XENSTORE_DATA, length %u", rechdr.length); + ret = restore_xenstore_data(ctx, restore_fd, rechdr.length); + break; + case REC_TYPE_EMULATOR_CONTEXT: + LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, + "Record: EMULATOR_CONTEXT, length %u", rechdr.length); + ret = restore_emulator_context(ctx, restore_fd, rechdr.length); + break; + default: + LIBXL__LOG(ctx, LIBXL__LOG_ERROR, + "Unknown record type: Got 0x%08x", rechdr.type); + ret = ERROR_FAIL; + break; + } + + /* Skip until an 8 byte boundary for the next record. */ + if (!ret) { + unsigned char pad[8]; + ssize_t len = ROUNDUP(rechdr.length, REC_ALIGN_ORDER) - rechdr.length; + + assert(len >= 0 && len < 8); + + if (libxl_read_exactly(ctx, restore_fd, pad, len, + "restore stream", "padding")) { + ret = ERROR_FAIL; + goto out; + } + } + } while (!ret && rechdr.type != REC_TYPE_END); + +out: + GC_FREE; + return ret; +} + +/* * Local variables: * mode: C * c-basic-offset: 4 diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h index 47fbf45..4128373 100644 --- a/tools/libxl/libxl_internal.h +++ b/tools/libxl/libxl_internal.h @@ -2876,6 +2876,11 @@ _hidden void libxl__domain_save_device_model(libxl__egc *egc, _hidden const char *libxl__device_model_savefile(libxl__gc *gc, uint32_t domid); +/*----- Domain restore functions -----*/ +/* TODO - make this asychronous */ +_hidden int libxl__domain_restore(libxl_ctx *ctx, int fd, uint32_t *domid, + libxl_domain_config *d_config /* TMP until json is sorted */ + ); /* * Convenience macros. -- 1.7.10.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |