Implement the new running/paused overrides for saved state management. Unfortunately, for virDomainSaveImageDefineXML, the saved state updates are write-only - I don't know of any way to expose a way to query the current run/pause setting of an existing save image file to the user without adding a new API or modifying the domain xml of virDomainSaveImageGetXMLDesc to include a new element to reflect the state bit encoded into the save image. However, I don't think this is a show-stopper, since the API is designed to leave the state bit alone unless an explicit flag is used to change it. * src/qemu/qemu_driver.c (qemuDomainSaveInternal) (qemuDomainSaveImageOpen): Adjust signature. (qemuDomainSaveFlags, qemuDomainManagedSave) (qemuDomainRestoreFlags, qemuDomainSaveImageGetXMLDesc) (qemuDomainSaveImageDefineXML, qemuDomainObjRestore): Adjust callers. --- src/qemu/qemu_driver.c | 68 ++++++++++++++++++++++++++++++++--------------- 1 files changed, 46 insertions(+), 22 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 6becd31..4ae6128 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -2213,7 +2213,7 @@ qemuCompressProgramName(int compress) static int qemuDomainSaveInternal(struct qemud_driver *driver, virDomainPtr dom, virDomainObjPtr vm, const char *path, - int compressed, bool bypass_cache, const char *xmlin) + int compressed, const char *xmlin, unsigned int flags) { char *xml = NULL; struct qemud_save_header header; @@ -2232,6 +2232,7 @@ qemuDomainSaveInternal(struct qemud_driver *driver, virDomainPtr dom, gid_t gid = getgid(); int directFlag = 0; virFileDirectFdPtr directFd = NULL; + bool bypass_cache = flags & VIR_DOMAIN_SAVE_BYPASS_CACHE; if (qemuProcessAutoDestroyActive(driver, vm)) { qemuReportError(VIR_ERR_OPERATION_INVALID, @@ -2267,6 +2268,11 @@ qemuDomainSaveInternal(struct qemud_driver *driver, virDomainPtr dom, goto endjob; } } + /* libvirt.c already guaranteed these two flags are exclusive. */ + if (flags & VIR_DOMAIN_SAVE_RUNNING) + header.was_running = 1; + else if (flags & VIR_DOMAIN_SAVE_PAUSED) + header.was_running = 0; /* Get XML for the domain. Restore needs only the inactive xml, * including secure. We should get the same result whether xmlin @@ -2508,7 +2514,9 @@ qemuDomainSaveFlags(virDomainPtr dom, const char *path, const char *dxml, int ret = -1; virDomainObjPtr vm = NULL; - virCheckFlags(VIR_DOMAIN_SAVE_BYPASS_CACHE, -1); + virCheckFlags(VIR_DOMAIN_SAVE_BYPASS_CACHE | + VIR_DOMAIN_SAVE_RUNNING | + VIR_DOMAIN_SAVE_PAUSED, -1); qemuDriverLock(driver); @@ -2546,8 +2554,7 @@ qemuDomainSaveFlags(virDomainPtr dom, const char *path, const char *dxml, } ret = qemuDomainSaveInternal(driver, dom, vm, path, compressed, - (flags & VIR_DOMAIN_SAVE_BYPASS_CACHE) != 0, - dxml); + dxml, flags); vm = NULL; cleanup: @@ -2585,7 +2592,9 @@ qemuDomainManagedSave(virDomainPtr dom, unsigned int flags) int ret = -1; int compressed; - virCheckFlags(VIR_DOMAIN_SAVE_BYPASS_CACHE, -1); + virCheckFlags(VIR_DOMAIN_SAVE_BYPASS_CACHE | + VIR_DOMAIN_SAVE_RUNNING | + VIR_DOMAIN_SAVE_PAUSED, -1); qemuDriverLock(driver); vm = virDomainFindByUUID(&driver->domains, dom->uuid); @@ -2616,8 +2625,7 @@ qemuDomainManagedSave(virDomainPtr dom, unsigned int flags) compressed = QEMUD_SAVE_FORMAT_RAW; ret = qemuDomainSaveInternal(driver, dom, vm, name, compressed, - (flags & VIR_DOMAIN_SAVE_BYPASS_CACHE) != 0, - NULL); + NULL, flags); vm = NULL; cleanup: @@ -3766,15 +3774,16 @@ cleanup: return ret; } -/* Return -1 on failure, -2 if edit was specified but xmlin does not - * represent any changes, and opened fd on all other success. */ +/* Return -1 on failure, -2 if edit was specified but xmlin and state + * (-1 for no change, 0 for paused, 1 for running) do not represent + * any changes, and opened fd on all other success. */ static int ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4) qemuDomainSaveImageOpen(struct qemud_driver *driver, const char *path, virDomainDefPtr *ret_def, struct qemud_save_header *ret_header, bool bypass_cache, virFileDirectFdPtr *directFd, - const char *xmlin, bool edit) + const char *xmlin, int state, bool edit) { int fd; struct qemud_save_header header; @@ -3854,7 +3863,8 @@ qemuDomainSaveImageOpen(struct qemud_driver *driver, goto error; } - if (edit && STREQ(xml, xmlin)) { + if (edit && STREQ(xml, xmlin) && + (state < 0 || state == header.was_running)) { VIR_FREE(xml); if (VIR_CLOSE(fd) < 0) { virReportSystemError(errno, _("cannot close file: %s"), path); @@ -3862,6 +3872,8 @@ qemuDomainSaveImageOpen(struct qemud_driver *driver, } return -2; } + if (state >= 0) + header.was_running = state; /* Create a domain from this XML */ if (!(def = virDomainDefParseString(driver->caps, xml, @@ -4024,14 +4036,22 @@ qemuDomainRestoreFlags(virConnectPtr conn, int ret = -1; struct qemud_save_header header; virFileDirectFdPtr directFd = NULL; + int state = -1; - virCheckFlags(VIR_DOMAIN_SAVE_BYPASS_CACHE, -1); + virCheckFlags(VIR_DOMAIN_SAVE_BYPASS_CACHE | + VIR_DOMAIN_SAVE_RUNNING | + VIR_DOMAIN_SAVE_PAUSED, -1); qemuDriverLock(driver); + if (flags & VIR_DOMAIN_SAVE_RUNNING) + state = 1; + else if (flags & VIR_DOMAIN_SAVE_PAUSED) + state = 0; + fd = qemuDomainSaveImageOpen(driver, path, &def, &header, (flags & VIR_DOMAIN_SAVE_BYPASS_CACHE) != 0, - &directFd, dxml, false); + &directFd, dxml, state, false); if (fd < 0) goto cleanup; @@ -4094,7 +4114,7 @@ qemuDomainSaveImageGetXMLDesc(virConnectPtr conn, const char *path, qemuDriverLock(driver); fd = qemuDomainSaveImageOpen(driver, path, &def, &header, false, NULL, - NULL, false); + NULL, -1, false); if (fd < 0) goto cleanup; @@ -4119,13 +4139,20 @@ qemuDomainSaveImageDefineXML(virConnectPtr conn, const char *path, struct qemud_save_header header; char *xml = NULL; size_t len; + int state = -1; - virCheckFlags(0, -1); + virCheckFlags(VIR_DOMAIN_SAVE_RUNNING | + VIR_DOMAIN_SAVE_PAUSED, -1); qemuDriverLock(driver); + if (flags & VIR_DOMAIN_SAVE_RUNNING) + state = 1; + else if (flags & VIR_DOMAIN_SAVE_PAUSED) + state = 0; + fd = qemuDomainSaveImageOpen(driver, path, &def, &header, false, NULL, - dxml, true); + dxml, state, true); if (fd < 0) { /* Check for special case of no change needed. */ @@ -4150,11 +4177,8 @@ qemuDomainSaveImageDefineXML(virConnectPtr conn, const char *path, goto cleanup; } - if (lseek(fd, sizeof(header), SEEK_SET) != sizeof(header)) { - virReportSystemError(errno, _("cannot seek in '%s'"), path); - goto cleanup; - } - if (safewrite(fd, xml, len) != len || + if (safewrite(fd, &header, sizeof(header) != sizeof(header)) || + safewrite(fd, xml, len) != len || VIR_CLOSE(fd) < 0) { virReportSystemError(errno, _("failed to write xml to '%s'"), path); goto cleanup; @@ -4185,7 +4209,7 @@ qemuDomainObjRestore(virConnectPtr conn, virFileDirectFdPtr directFd = NULL; fd = qemuDomainSaveImageOpen(driver, path, &def, &header, - bypass_cache, &directFd, NULL, false); + bypass_cache, &directFd, NULL, -1, false); if (fd < 0) goto cleanup; -- 1.7.4.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list