if (!(meta = virStorageFileGetMetadataFromBuf(target->path,
header, len,
- target->format))) {
+ target->format,
+ backingStore,
+ backingStoreFormat))) {
ret = -1;
goto error;
}
VIR_FORCE_CLOSE(fd);
- if (meta && meta->backingStore) {
- *backingStore = meta->backingStore;
- meta->backingStore = NULL;
- if (meta->backingStoreFormat == VIR_STORAGE_FILE_AUTO &&
- virStorageIsFile(*backingStore)) {
- if ((ret = virStorageFileProbeFormat(*backingStore, -1, -1)) < 0) {
- /* If the backing file is currently unavailable, only log an error,
- * but continue. Returning -1 here would disable the whole storage
- * pool, making it unavailable for even maintenance. */
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("cannot probe backing volume format: %s"),
- *backingStore);
- ret = -3;
- } else {
- *backingStoreFormat = ret;
- ret = 0;
- }
+ if (meta && *backingStore &&
+ *backingStoreFormat == VIR_STORAGE_FILE_AUTO &&
+ virStorageIsFile(*backingStore)) {
+ if ((ret = virStorageFileProbeFormat(*backingStore, -1, -1)) < 0) {
+ /* If the backing file is currently unavailable, only log an error,
+ * but continue. Returning -1 here would disable the whole storage
+ * pool, making it unavailable for even maintenance. */
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("cannot probe backing volume format: %s"),
+ *backingStore);
+ ret = -3;
} else {
- *backingStoreFormat = meta->backingStoreFormat;
+ *backingStoreFormat = ret;
ret = 0;
}
} else {
len)) < 0)
goto cleanup;
if (!(meta = virStorageFileGetMetadataFromBuf(name, header, len,
- vol->target.format)))
+ vol->target.format,
+ &vol->backingStore.path,
+ &vol->backingStore.format)))
goto cleanup;
- if (meta->backingStore) {
- vol->backingStore.path = meta->backingStore;
- meta->backingStore = NULL;
- vol->backingStore.format = meta->backingStoreFormat;
- if (vol->backingStore.format < 0)
- vol->backingStore.format = VIR_STORAGE_FILE_RAW;
- }
+ if (vol->backingStore.path &&
+ vol->backingStore.format < 0)
+ vol->backingStore.format = VIR_STORAGE_FILE_RAW;
if (meta->capacity)
vol->target.capacity = meta->capacity;
if (meta->encryption) {
* information about the file and its backing store. */
static int ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2)
ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4) ATTRIBUTE_NONNULL(7)
+ATTRIBUTE_NONNULL(8) ATTRIBUTE_NONNULL(9)
virStorageFileGetMetadataInternal(const char *path,
const char *canonPath,
const char *directory,
char *buf,
size_t len,
int format,
- virStorageFileMetadataPtr meta)
+ virStorageFileMetadataPtr meta,
+ char **backingStore,
+ int *backingFormat)
{
int ret = -1;
}
if (fileTypeInfo[format].getBackingStore != NULL) {
- char *backing;
- int backingFormat;
+ char *backing = NULL;
int store = fileTypeInfo[format].getBackingStore(&backing,
- &backingFormat,
+ backingFormat,
buf, len);
if (store == BACKING_STORE_INVALID)
goto done;
/* the backing file is (currently) unavailable, treat this
* file as standalone:
* backingStoreRaw is kept to mark broken image chains */
- backingFormat = VIR_STORAGE_FILE_NONE;
+ *backingFormat = VIR_STORAGE_FILE_NONE;
VIR_WARN("Backing file '%s' of image '%s' is missing.",
meta->backingStoreRaw, path);
}
} else {
- if (VIR_STRDUP(meta->backingStoreRaw, backing) < 0) {
- VIR_FREE(backing);
- goto cleanup;
- }
- backingFormat = VIR_STORAGE_FILE_RAW;
+ *backingStore = backing;
+ backing = NULL;
+ *backingFormat = VIR_STORAGE_FILE_RAW;
}
VIR_FREE(backing);
- meta->backingStoreFormat = backingFormat;
} else {
meta->backingStore = NULL;
- meta->backingStoreFormat = VIR_STORAGE_FILE_NONE;
+ *backingFormat = VIR_STORAGE_FILE_NONE;
}
}
* @buf: header bytes from @path
* @len: length of @buf
* @format: expected image format
+ * @backing: output malloc'd name of backing image, if any
+ * @backingFormat: format of @backing
*
* Extract metadata about the storage volume with the specified
* image format. If image format is VIR_STORAGE_FILE_AUTO, it
* format, since a malicious guest can turn a raw file into any
* other non-raw format at will.
*
- * If the returned meta.backingStoreFormat is VIR_STORAGE_FILE_AUTO
+ * If the returned @backingFormat is VIR_STORAGE_FILE_AUTO
* it indicates the image didn't specify an explicit format for its
* backing store. Callers are advised against probing for the
* backing store format in this case.
virStorageFileGetMetadataFromBuf(const char *path,
char *buf,
size_t len,
- int format)
+ int format,
+ char **backing,
+ int *backingFormat)
{
virStorageFileMetadataPtr ret = NULL;
char *canonPath;
goto cleanup;
if (virStorageFileGetMetadataInternal(path, canonPath, ".", buf, len,
- format, ret) < 0) {
+ format, ret, backing,
+ backingFormat) < 0) {
virStorageFileFreeMetadata(ret);
ret = NULL;
}
}
ret = virStorageFileGetMetadataInternal(path, canonPath, directory,
- buf, len, format, meta);
+ buf, len, format, meta,
+ &meta->backingStoreRaw,
+ &meta->backingStoreFormat);
if (ret == 0) {
if (S_ISREG(sb.st_mode))