|
|
3e5111 |
From 4a304d9114e1b2e2f69fdb0857501ad8db03d17b Mon Sep 17 00:00:00 2001
|
|
|
3e5111 |
Message-Id: <4a304d9114e1b2e2f69fdb0857501ad8db03d17b@dist-git>
|
|
|
3e5111 |
From: Jiri Denemark <jdenemar@redhat.com>
|
|
|
3e5111 |
Date: Tue, 6 Jun 2017 23:41:57 +0200
|
|
|
3e5111 |
Subject: [PATCH] qemu: Refactor qemuDomainSaveHeader
|
|
|
3e5111 |
|
|
|
3e5111 |
The function is now called virQEMUSaveDataWrite and it is now doing
|
|
|
3e5111 |
everything it needs to save both the save image header and domain XML to
|
|
|
3e5111 |
a file. Be it a new file or an existing file in which a user wants to
|
|
|
3e5111 |
change the domain XML.
|
|
|
3e5111 |
|
|
|
3e5111 |
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
|
|
|
3e5111 |
Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
|
|
|
3e5111 |
(cherry picked from commit 33ae270bee012fc89d7b8bb23986ce837ee21b0e)
|
|
|
3e5111 |
|
|
|
3e5111 |
https://bugzilla.redhat.com/show_bug.cgi?id=1441662
|
|
|
3e5111 |
|
|
|
3e5111 |
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
|
|
|
3e5111 |
---
|
|
|
3e5111 |
src/qemu/qemu_driver.c | 98 ++++++++++++++++++++++++++++++--------------------
|
|
|
3e5111 |
1 file changed, 60 insertions(+), 38 deletions(-)
|
|
|
3e5111 |
|
|
|
3e5111 |
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
|
|
|
3e5111 |
index a0b607b419..1629f27470 100644
|
|
|
3e5111 |
--- a/src/qemu/qemu_driver.c
|
|
|
3e5111 |
+++ b/src/qemu/qemu_driver.c
|
|
|
3e5111 |
@@ -2837,7 +2837,7 @@ virQEMUSaveDataFree(virQEMUSaveHeaderPtr header)
|
|
|
3e5111 |
|
|
|
3e5111 |
|
|
|
3e5111 |
static virQEMUSaveHeaderPtr
|
|
|
3e5111 |
-virQEMUSaveDataNew(char *domXML,
|
|
|
3e5111 |
+virQEMUSaveDataNew(char *domXML ATTRIBUTE_UNUSED,
|
|
|
3e5111 |
bool running,
|
|
|
3e5111 |
int compressed)
|
|
|
3e5111 |
{
|
|
|
3e5111 |
@@ -2850,34 +2850,66 @@ virQEMUSaveDataNew(char *domXML,
|
|
|
3e5111 |
header->version = QEMU_SAVE_VERSION;
|
|
|
3e5111 |
header->was_running = running ? 1 : 0;
|
|
|
3e5111 |
header->compressed = compressed;
|
|
|
3e5111 |
- header->data_len = strlen(domXML) + 1;
|
|
|
3e5111 |
|
|
|
3e5111 |
return header;
|
|
|
3e5111 |
}
|
|
|
3e5111 |
|
|
|
3e5111 |
|
|
|
3e5111 |
-/* return -errno on failure, or 0 on success */
|
|
|
3e5111 |
+/* virQEMUSaveDataWrite:
|
|
|
3e5111 |
+ *
|
|
|
3e5111 |
+ * Writes libvirt's header (including domain XML) into a saved image of a
|
|
|
3e5111 |
+ * running domain. If @header has data_len filled in (because it was previously
|
|
|
3e5111 |
+ * read from the file), the function will make sure the new data will fit
|
|
|
3e5111 |
+ * within data_len.
|
|
|
3e5111 |
+ *
|
|
|
3e5111 |
+ * Returns -1 on failure, or 0 on success.
|
|
|
3e5111 |
+ */
|
|
|
3e5111 |
static int
|
|
|
3e5111 |
-qemuDomainSaveHeader(int fd, const char *path, const char *xml,
|
|
|
3e5111 |
- virQEMUSaveHeaderPtr header)
|
|
|
3e5111 |
+virQEMUSaveDataWrite(virQEMUSaveHeaderPtr header,
|
|
|
3e5111 |
+ const char *xml,
|
|
|
3e5111 |
+ int fd,
|
|
|
3e5111 |
+ const char *path)
|
|
|
3e5111 |
{
|
|
|
3e5111 |
- int ret = 0;
|
|
|
3e5111 |
+ size_t len;
|
|
|
3e5111 |
+ int ret = -1;
|
|
|
3e5111 |
+ size_t zerosLen = 0;
|
|
|
3e5111 |
+ char *zeros = NULL;
|
|
|
3e5111 |
+
|
|
|
3e5111 |
+ len = strlen(xml) + 1;
|
|
|
3e5111 |
+
|
|
|
3e5111 |
+ if (header->data_len > 0) {
|
|
|
3e5111 |
+ if (len > header->data_len) {
|
|
|
3e5111 |
+ virReportError(VIR_ERR_OPERATION_FAILED, "%s",
|
|
|
3e5111 |
+ _("new xml too large to fit in file"));
|
|
|
3e5111 |
+ goto cleanup;
|
|
|
3e5111 |
+ }
|
|
|
3e5111 |
+
|
|
|
3e5111 |
+ zerosLen = header->data_len - len;
|
|
|
3e5111 |
+ if (VIR_ALLOC_N(zeros, zerosLen) < 0)
|
|
|
3e5111 |
+ goto cleanup;
|
|
|
3e5111 |
+ } else {
|
|
|
3e5111 |
+ header->data_len = len;
|
|
|
3e5111 |
+ }
|
|
|
3e5111 |
|
|
|
3e5111 |
if (safewrite(fd, header, sizeof(*header)) != sizeof(*header)) {
|
|
|
3e5111 |
- ret = -errno;
|
|
|
3e5111 |
- virReportError(VIR_ERR_OPERATION_FAILED,
|
|
|
3e5111 |
- _("failed to write header to domain save file '%s'"),
|
|
|
3e5111 |
- path);
|
|
|
3e5111 |
- goto endjob;
|
|
|
3e5111 |
+ virReportSystemError(errno,
|
|
|
3e5111 |
+ _("failed to write header to domain save file '%s'"),
|
|
|
3e5111 |
+ path);
|
|
|
3e5111 |
+ goto cleanup;
|
|
|
3e5111 |
}
|
|
|
3e5111 |
|
|
|
3e5111 |
- if (safewrite(fd, xml, header->data_len) != header->data_len) {
|
|
|
3e5111 |
- ret = -errno;
|
|
|
3e5111 |
- virReportError(VIR_ERR_OPERATION_FAILED,
|
|
|
3e5111 |
- _("failed to write xml to '%s'"), path);
|
|
|
3e5111 |
- goto endjob;
|
|
|
3e5111 |
+ if (safewrite(fd, xml, header->data_len) != header->data_len ||
|
|
|
3e5111 |
+ safewrite(fd, zeros, zerosLen) != zerosLen) {
|
|
|
3e5111 |
+ virReportSystemError(errno,
|
|
|
3e5111 |
+ _("failed to write domain xml to '%s'"),
|
|
|
3e5111 |
+ path);
|
|
|
3e5111 |
+ goto cleanup;
|
|
|
3e5111 |
}
|
|
|
3e5111 |
- endjob:
|
|
|
3e5111 |
+
|
|
|
3e5111 |
+ ret = 0;
|
|
|
3e5111 |
+
|
|
|
3e5111 |
+ cleanup:
|
|
|
3e5111 |
+ VIR_FREE(zeros);
|
|
|
3e5111 |
return ret;
|
|
|
3e5111 |
}
|
|
|
3e5111 |
|
|
|
3e5111 |
@@ -3132,8 +3164,7 @@ qemuDomainSaveMemory(virQEMUDriverPtr driver,
|
|
|
3e5111 |
if (!(wrapperFd = virFileWrapperFdNew(&fd, path, wrapperFlags)))
|
|
|
3e5111 |
goto cleanup;
|
|
|
3e5111 |
|
|
|
3e5111 |
- /* Write header to file, followed by XML */
|
|
|
3e5111 |
- if (qemuDomainSaveHeader(fd, path, domXML, header) < 0)
|
|
|
3e5111 |
+ if (virQEMUSaveDataWrite(header, domXML, fd, path) < 0)
|
|
|
3e5111 |
goto cleanup;
|
|
|
3e5111 |
|
|
|
3e5111 |
/* Perform the migration */
|
|
|
3e5111 |
@@ -6620,7 +6651,6 @@ qemuDomainSaveImageDefineXML(virConnectPtr conn, const char *path,
|
|
|
3e5111 |
virDomainDefPtr newdef = NULL;
|
|
|
3e5111 |
int fd = -1;
|
|
|
3e5111 |
char *xml = NULL;
|
|
|
3e5111 |
- size_t len;
|
|
|
3e5111 |
virQEMUSaveHeaderPtr header = NULL;
|
|
|
3e5111 |
int state = -1;
|
|
|
3e5111 |
|
|
|
3e5111 |
@@ -6656,30 +6686,22 @@ qemuDomainSaveImageDefineXML(virConnectPtr conn, const char *path,
|
|
|
3e5111 |
|
|
|
3e5111 |
VIR_FREE(xml);
|
|
|
3e5111 |
|
|
|
3e5111 |
- xml = qemuDomainDefFormatXML(driver, newdef,
|
|
|
3e5111 |
- VIR_DOMAIN_XML_INACTIVE |
|
|
|
3e5111 |
- VIR_DOMAIN_XML_SECURE |
|
|
|
3e5111 |
- VIR_DOMAIN_XML_MIGRATABLE);
|
|
|
3e5111 |
- if (!xml)
|
|
|
3e5111 |
- goto cleanup;
|
|
|
3e5111 |
- len = strlen(xml) + 1;
|
|
|
3e5111 |
-
|
|
|
3e5111 |
- if (len > header->data_len) {
|
|
|
3e5111 |
- virReportError(VIR_ERR_OPERATION_FAILED, "%s",
|
|
|
3e5111 |
- _("new xml too large to fit in file"));
|
|
|
3e5111 |
- goto cleanup;
|
|
|
3e5111 |
- }
|
|
|
3e5111 |
- if (VIR_EXPAND_N(xml, len, header->data_len - len) < 0)
|
|
|
3e5111 |
+ if (!(xml = qemuDomainDefFormatXML(driver, newdef,
|
|
|
3e5111 |
+ VIR_DOMAIN_XML_INACTIVE |
|
|
|
3e5111 |
+ VIR_DOMAIN_XML_SECURE |
|
|
|
3e5111 |
+ VIR_DOMAIN_XML_MIGRATABLE)))
|
|
|
3e5111 |
goto cleanup;
|
|
|
3e5111 |
|
|
|
3e5111 |
if (lseek(fd, 0, SEEK_SET) != 0) {
|
|
|
3e5111 |
virReportSystemError(errno, _("cannot seek in '%s'"), path);
|
|
|
3e5111 |
goto cleanup;
|
|
|
3e5111 |
}
|
|
|
3e5111 |
- if (safewrite(fd, &header, sizeof(header)) != sizeof(header) ||
|
|
|
3e5111 |
- safewrite(fd, xml, len) != len ||
|
|
|
3e5111 |
- VIR_CLOSE(fd) < 0) {
|
|
|
3e5111 |
- virReportSystemError(errno, _("failed to write xml to '%s'"), path);
|
|
|
3e5111 |
+
|
|
|
3e5111 |
+ if (virQEMUSaveDataWrite(header, xml, fd, path) < 0)
|
|
|
3e5111 |
+ goto cleanup;
|
|
|
3e5111 |
+
|
|
|
3e5111 |
+ if (VIR_CLOSE(fd) < 0) {
|
|
|
3e5111 |
+ virReportSystemError(errno, _("failed to write header data to '%s'"), path);
|
|
|
3e5111 |
goto cleanup;
|
|
|
3e5111 |
}
|
|
|
3e5111 |
|
|
|
3e5111 |
--
|
|
|
3e5111 |
2.13.1
|
|
|
3e5111 |
|