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(a)suse.com>
---
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