diff --git a/tools/libxc/xc_domain_restore.c b/tools/libxc/xc_domain_restore.c index c9f3916b34..7c64a4929b 100644 --- a/tools/libxc/xc_domain_restore.c +++ b/tools/libxc/xc_domain_restore.c @@ -494,13 +494,18 @@ static int buffer_tail_hvm(xc_interface *xch, struct restore_ctx *ctx, return -1; } - /* The normal live-migration QEMU record has no length information. + /* The legacy live-migration QEMU record has no length information. * Short of reimplementing the QEMU parser, we're forced to just read - * until EOF. Remus gets around this by sending a different signature - * which includes a length prefix */ + * until EOF. + * + * Gets around this by sending a different signatures for the new + * live-migration QEMU record and Remus which includes a length + * prefix + */ if ( !memcmp(qemusig, "QemuDeviceModelRecord", sizeof(qemusig)) ) return compat_buffer_qemu(xch, ctx, fd, buf); - else if ( !memcmp(qemusig, "RemusDeviceModelState", sizeof(qemusig)) ) + else if ( !memcmp(qemusig, "DeviceModelRecord0002", sizeof(qemusig)) || + !memcmp(qemusig, "RemusDeviceModelState", sizeof(qemusig)) ) return buffer_qemu(xch, ctx, fd, buf); qemusig[20] = '\0'; diff --git a/tools/libxc/xg_save_restore.h b/tools/libxc/xg_save_restore.h index 2c82ce7404..b13bdef649 100644 --- a/tools/libxc/xg_save_restore.h +++ b/tools/libxc/xg_save_restore.h @@ -104,8 +104,9 @@ * Qemu context: * char[21] : Signature: * "QemuDeviceModelRecord" : Read Qemu save data until EOF - * "RemusDeviceModelState" : uint32_t length field followed by that many + * "DeviceModelRecord0002" : uint32_t length field followed by that many * bytes of Qemu save data + * "RemusDeviceModelState" : Currently the same as "DeviceModelRecord0002". * * PV TAIL: * diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c index f40d41b7fc..79d9f0d319 100644 --- a/tools/libxl/libxl.c +++ b/tools/libxl/libxl.c @@ -686,8 +686,8 @@ int libxl_domain_suspend(libxl_ctx *ctx, libxl_domain_suspend_info *info, int debug = info != NULL && info->flags & XL_SUSPEND_DEBUG; int rc = 0; - libxl__domain_suspend_common(ctx, domid, fd, hvm, live, debug); - if (hvm) + rc = libxl__domain_suspend_common(ctx, domid, fd, hvm, live, debug); + if (!rc && hvm) rc = libxl__domain_save_device_model(ctx, domid, fd); return rc; } diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c index 5352f65ef6..bbba8057e8 100644 --- a/tools/libxl/libxl_dom.c +++ b/tools/libxl/libxl_dom.c @@ -442,14 +442,17 @@ int libxl__domain_suspend_common(libxl_ctx *ctx, uint32_t domid, int fd, callbacks.switch_qemu_logdirty = libxl__domain_suspend_common_switch_qemu_logdirty; callbacks.data = &si; - xc_domain_save(ctx->xch, fd, domid, 0, 0, flags, &callbacks, hvm); + rc = xc_domain_save(ctx->xch, fd, domid, 0, 0, flags, &callbacks, hvm); + if ( rc ) { + LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "saving domain"); + rc = ERROR_FAIL; + } if (si.suspend_eventchn > 0) xc_suspend_evtchn_release(ctx->xch, si.xce, domid, si.suspend_eventchn); if (si.xce > 0) xc_evtchn_close(si.xce); - rc = 0; out: libxl__free_all(&gc); return rc; @@ -461,15 +464,32 @@ int libxl__domain_save_device_model(libxl_ctx *ctx, uint32_t domid, int fd) int fd2, c; char buf[1024]; char *filename = libxl__sprintf(&gc, "/var/lib/xen/qemu-save.%d", domid); + 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(ctx, domid, "paused", NULL, NULL); + if (stat(filename, &st) < 0) + { + LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "Unable to stat qemu save file\n"); + return ERROR_FAIL; + } + + qemu_state_len = st.st_size; + LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, "Qemu state is %d bytes\n", qemu_state_len); + c = libxl_write_exactly(ctx, fd, QEMU_SIGNATURE, strlen(QEMU_SIGNATURE), "saved-state file", "qemu signature"); if (c) return c; + + c = libxl_write_exactly(ctx, fd, &qemu_state_len, sizeof(qemu_state_len), + "saved-state file", "saved-state length"); + if (c) + return c; + fd2 = open(filename, O_RDONLY); while ((c = read(fd2, buf, sizeof(buf))) != 0) { if (c < 0) { diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h index e89ac2fe9f..e3fc22dd9f 100644 --- a/tools/libxl/libxl_internal.h +++ b/tools/libxl/libxl_internal.h @@ -44,7 +44,7 @@ #define LIBXL_PV_EXTRA_MEMORY 1024 #define LIBXL_HVM_EXTRA_MEMORY 2048 #define LIBXL_MIN_DOM0_MEM (128*1024) -#define QEMU_SIGNATURE "QemuDeviceModelRecord" +#define QEMU_SIGNATURE "DeviceModelRecord0002" #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))