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