The virStorageFileGetBackingStoreStr method has overloaded the NULL
return value to indicate both no backing available and a fatal
error dealing with it.
The caller is thus not able to correctly propagate the error
messages.
Signed-off-by: Daniel P. Berrangé <berrange(a)redhat.com>
---
src/qemu/qemu_driver.c | 15 +++++++++------
src/util/virstoragefile.c | 49 +++++++++++++++++++++++++++++++----------------
src/util/virstoragefile.h | 5 +++--
3 files changed, 44 insertions(+), 25 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 7484b00e23..672c5372eb 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -14608,12 +14608,15 @@ qemuDomainSnapshotDiskDataCollect(virQEMUDriverPtr driver,
/* relative backing store paths need to be updated so that relative
* block commit still works */
- if (reuse &&
- (backingStoreStr = virStorageFileGetBackingStoreStr(dd->src))) {
- if (virStorageIsRelative(backingStoreStr))
- VIR_STEAL_PTR(dd->relPath, backingStoreStr);
- else
- VIR_FREE(backingStoreStr);
+ if (reuse) {
+ if (virStorageFileGetBackingStoreStr(dd->src, &backingStoreStr) <
0)
+ goto error;
+ if (backingStoreStr != NULL) {
+ if (virStorageIsRelative(backingStoreStr))
+ VIR_STEAL_PTR(dd->relPath, backingStoreStr);
+ else
+ VIR_FREE(backingStoreStr);
+ }
}
/* Note that it's unsafe to assume that the disks in the persistent
diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
index 531540ac91..f09035cd4a 100644
--- a/src/util/virstoragefile.c
+++ b/src/util/virstoragefile.c
@@ -4357,14 +4357,8 @@ virStorageFileRead(virStorageSourcePtr src,
return -1;
}
- if (!src->drv->backend->storageFileRead) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("storage file reading is not supported for "
- "storage type %s (protocol: %s)"),
- virStorageTypeToString(src->type),
- virStorageNetProtocolTypeToString(src->protocol));
+ if (!src->drv->backend->storageFileRead)
return -2;
- }
ret = src->drv->backend->storageFileRead(src, offset, len, buf);
@@ -4551,8 +4545,15 @@ virStorageFileGetMetadataRecurse(virStorageSourcePtr src,
goto cleanup;
if ((headerLen = virStorageFileRead(src, 0, VIR_STORAGE_MAX_HEADER,
- &buf)) < 0)
+ &buf)) < 0) {
+ if (headerLen == -2)
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("storage file reading is not supported for "
+ "storage type %s (protocol: %s)"),
+ virStorageTypeToString(src->type),
+ virStorageNetProtocolTypeToString(src->protocol));
goto cleanup;
+ }
if (virStorageFileGetMetadataInternal(src, buf, headerLen,
&backingFormat) < 0)
@@ -4664,24 +4665,36 @@ virStorageFileGetMetadata(virStorageSourcePtr src,
* In case when the string can't be retrieved or does not exist NULL is
* returned.
*/
-char *
-virStorageFileGetBackingStoreStr(virStorageSourcePtr src)
+int
+virStorageFileGetBackingStoreStr(virStorageSourcePtr src,
+ char **backing)
{
virStorageSourcePtr tmp = NULL;
char *buf = NULL;
ssize_t headerLen;
- char *ret = NULL;
+ int ret = -1;
+ int rv;
+
+ *backing = NULL;
/* exit if we can't load information about the current image */
if (!virStorageFileSupportsBackingChainTraversal(src))
- return NULL;
+ return 0;
- if (virStorageFileAccess(src, F_OK) < 0)
- return NULL;
+ rv = virStorageFileAccess(src, F_OK);
+ if (rv == -2)
+ return 0;
+ if (rv < 0) {
+ virStorageFileReportBrokenChain(errno, src, src);
+ return -1;
+ }
if ((headerLen = virStorageFileRead(src, 0, VIR_STORAGE_MAX_HEADER,
- &buf)) < 0)
- return NULL;
+ &buf)) < 0) {
+ if (headerLen == -2)
+ return 0;
+ return -1;
+ }
if (!(tmp = virStorageSourceCopy(src, false)))
goto cleanup;
@@ -4689,7 +4702,9 @@ virStorageFileGetBackingStoreStr(virStorageSourcePtr src)
if (virStorageFileGetMetadataInternal(tmp, buf, headerLen, NULL) < 0)
goto cleanup;
- VIR_STEAL_PTR(ret, tmp->backingStoreRaw);
+ VIR_STEAL_PTR(*backing, tmp->backingStoreRaw);
+
+ ret = 0;
cleanup:
VIR_FREE(buf);
diff --git a/src/util/virstoragefile.h b/src/util/virstoragefile.h
index d129e81978..b92c1c47dd 100644
--- a/src/util/virstoragefile.h
+++ b/src/util/virstoragefile.h
@@ -474,8 +474,9 @@ int virStorageFileGetMetadata(virStorageSourcePtr src,
bool report_broken)
ATTRIBUTE_NONNULL(1);
-char *virStorageFileGetBackingStoreStr(virStorageSourcePtr src)
- ATTRIBUTE_NONNULL(1);
+int virStorageFileGetBackingStoreStr(virStorageSourcePtr src,
+ char **backing)
+ ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
void virStorageFileReportBrokenChain(int errcode,
virStorageSourcePtr src,
--
2.14.3