[PATCH V2 1/3] qemu: Move unlinking corrupt save image file to caller

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



qemuDomainObjRestore is the only caller of qemuSaveImageOpen that
requests an unlink of a corrupted save image. Provide a function to
check for a corrupt image and move unlinking it to qemuDomainObjRestore.

Signed-off-by: Jim Fehlig <jfehlig@xxxxxxxx>
---
 src/qemu/qemu_driver.c    | 23 ++++++++++-----
 src/qemu/qemu_saveimage.c | 59 +++++++++++++++++++++------------------
 src/qemu/qemu_saveimage.h |  8 ++++--
 src/qemu/qemu_snapshot.c  |  3 +-
 4 files changed, 55 insertions(+), 38 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index da714f1975..2e80ce7921 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -5777,7 +5777,7 @@ qemuDomainRestoreInternal(virConnectPtr conn,
 
     fd = qemuSaveImageOpen(driver, NULL, path, &def, &data,
                            (flags & VIR_DOMAIN_SAVE_BYPASS_CACHE) != 0,
-                           &wrapperFd, false, false);
+                           &wrapperFd, false);
     if (fd < 0)
         goto cleanup;
 
@@ -5912,7 +5912,7 @@ qemuDomainSaveImageGetXMLDesc(virConnectPtr conn, const char *path,
     virCheckFlags(VIR_DOMAIN_SAVE_IMAGE_XML_SECURE, NULL);
 
     fd = qemuSaveImageOpen(driver, NULL, path, &def, &data,
-                           false, NULL, false, false);
+                           false, NULL, false);
 
     if (fd < 0)
         goto cleanup;
@@ -5949,7 +5949,7 @@ qemuDomainSaveImageDefineXML(virConnectPtr conn, const char *path,
         state = 0;
 
     fd = qemuSaveImageOpen(driver, NULL, path, &def, &data,
-                           false, NULL, true, false);
+                           false, NULL, true);
 
     if (fd < 0)
         goto cleanup;
@@ -6030,7 +6030,7 @@ qemuDomainManagedSaveGetXMLDesc(virDomainPtr dom, unsigned int flags)
     }
 
     if ((fd = qemuSaveImageOpen(driver, priv->qemuCaps, path, &def, &data,
-                                false, NULL, false, false)) < 0)
+                                false, NULL, false)) < 0)
         goto cleanup;
 
     ret = qemuDomainDefFormatXML(driver, priv->qemuCaps, def, flags);
@@ -6094,10 +6094,19 @@ qemuDomainObjRestore(virConnectPtr conn,
     virFileWrapperFd *wrapperFd = NULL;
 
     fd = qemuSaveImageOpen(driver, NULL, path, &def, &data,
-                           bypass_cache, &wrapperFd, false, true);
+                           bypass_cache, &wrapperFd, false);
     if (fd < 0) {
-        if (fd == -3)
-            ret = 1;
+        if (qemuSaveImageIsCorrupt(driver, path)) {
+            if (unlink(path) < 0) {
+                virReportSystemError(errno,
+                                     _("cannot remove corrupt file: %1$s"),
+                                     path);
+                ret = -1;
+            } else {
+                virResetLastError();
+                ret = 1;
+            }
+        }
         goto cleanup;
     }
 
diff --git a/src/qemu/qemu_saveimage.c b/src/qemu/qemu_saveimage.c
index 69617e07eb..385ac8a649 100644
--- a/src/qemu/qemu_saveimage.c
+++ b/src/qemu/qemu_saveimage.c
@@ -520,6 +520,35 @@ qemuSaveImageGetCompressionProgram(const char *imageFormat,
     return -1;
 }
 
+/**
+ * qemuSaveImageIsCorrupt:
+ * @driver: qemu driver data
+ * @path: path of the save image
+ *
+ * Returns true if the save image file identified by @path does not exist or
+ * has a corrupt header. Returns false otherwise.
+ */
+
+bool
+qemuSaveImageIsCorrupt(virQEMUDriver *driver, const char *path)
+{
+    g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
+    VIR_AUTOCLOSE fd = -1;
+    virQEMUSaveHeader header;
+
+    if ((fd = qemuDomainOpenFile(cfg, NULL, path, O_RDONLY, NULL)) < 0)
+        return true;
+
+    if (saferead(fd, &header, sizeof(header)) != sizeof(header))
+        return true;
+
+    if (memcmp(header.magic, QEMU_SAVE_MAGIC, sizeof(header.magic)) != 0 ||
+        memcmp(header.magic, QEMU_SAVE_PARTIAL, sizeof(header.magic)) == 0)
+        return true;
+
+    return false;
+}
+
 
 /**
  * qemuSaveImageOpen:
@@ -531,11 +560,10 @@ qemuSaveImageGetCompressionProgram(const char *imageFormat,
  * @bypass_cache: bypass cache when opening the file
  * @wrapperFd: returns the file wrapper structure
  * @open_write: open the file for writing (for updates)
- * @unlink_corrupt: remove the image file if it is corrupted
  *
  * Returns the opened fd of the save image file and fills the appropriate fields
- * on success. On error returns -1 on most failures, -3 if corrupt image was
- * unlinked (no error raised).
+ * on success. On error returns -1 on most failures, -3 if a corrupt image was
+ * detected.
  */
 int
 qemuSaveImageOpen(virQEMUDriver *driver,
@@ -545,8 +573,7 @@ qemuSaveImageOpen(virQEMUDriver *driver,
                   virQEMUSaveData **ret_data,
                   bool bypass_cache,
                   virFileWrapperFd **wrapperFd,
-                  bool open_write,
-                  bool unlink_corrupt)
+                  bool open_write)
 {
     g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
     VIR_AUTOCLOSE fd = -1;
@@ -580,17 +607,6 @@ qemuSaveImageOpen(virQEMUDriver *driver,
 
     header = &data->header;
     if (saferead(fd, header, sizeof(*header)) != sizeof(*header)) {
-        if (unlink_corrupt) {
-            if (unlink(path) < 0) {
-                virReportSystemError(errno,
-                                     _("cannot remove corrupt file: %1$s"),
-                                     path);
-                return -1;
-            } else {
-                return -3;
-            }
-        }
-
         virReportError(VIR_ERR_OPERATION_FAILED,
                        "%s", _("failed to read qemu header"));
         return -1;
@@ -598,17 +614,6 @@ qemuSaveImageOpen(virQEMUDriver *driver,
 
     if (memcmp(header->magic, QEMU_SAVE_MAGIC, sizeof(header->magic)) != 0) {
         if (memcmp(header->magic, QEMU_SAVE_PARTIAL, sizeof(header->magic)) == 0) {
-            if (unlink_corrupt) {
-                if (unlink(path) < 0) {
-                    virReportSystemError(errno,
-                                         _("cannot remove corrupt file: %1$s"),
-                                         path);
-                    return -1;
-                } else {
-                    return -3;
-                }
-            }
-
             virReportError(VIR_ERR_OPERATION_FAILED, "%s",
                            _("save image is incomplete"));
             return -1;
diff --git a/src/qemu/qemu_saveimage.h b/src/qemu/qemu_saveimage.h
index 0e58dd14b6..dc49f8463f 100644
--- a/src/qemu/qemu_saveimage.h
+++ b/src/qemu/qemu_saveimage.h
@@ -69,6 +69,11 @@ qemuSaveImageStartVM(virConnectPtr conn,
                      virDomainAsyncJob asyncJob)
     ATTRIBUTE_NONNULL(4) ATTRIBUTE_NONNULL(5) ATTRIBUTE_NONNULL(6);
 
+bool
+qemuSaveImageIsCorrupt(virQEMUDriver *driver,
+                       const char *path)
+    ATTRIBUTE_NONNULL(2);
+
 int
 qemuSaveImageOpen(virQEMUDriver *driver,
                   virQEMUCaps *qemuCaps,
@@ -77,8 +82,7 @@ qemuSaveImageOpen(virQEMUDriver *driver,
                   virQEMUSaveData **ret_data,
                   bool bypass_cache,
                   virFileWrapperFd **wrapperFd,
-                  bool open_write,
-                  bool unlink_corrupt)
+                  bool open_write)
     ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4);
 
 int
diff --git a/src/qemu/qemu_snapshot.c b/src/qemu/qemu_snapshot.c
index 5273348aeb..b9c3983472 100644
--- a/src/qemu/qemu_snapshot.c
+++ b/src/qemu/qemu_snapshot.c
@@ -2379,8 +2379,7 @@ qemuSnapshotRevertExternalPrepare(virDomainObj *vm,
         memdata->path = snapdef->memorysnapshotfile;
         memdata->fd = qemuSaveImageOpen(driver, NULL, memdata->path,
                                         &savedef, &memdata->data,
-                                        false, NULL,
-                                        false, false);
+                                        false, NULL, false);
 
         if (memdata->fd < 0)
             return -1;
-- 
2.43.0



[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]

  Powered by Linux