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