mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-14 08:35:15 +00:00
storage: remember relative names in backing chain
In order to search for a backing file name as literally present in a chain, we need to remember if the chain had relative names. Also, searching for absolute names is easier if we only have to canonicalize once, rather than on every iteration. * src/util/storage_file.h (_virStorageFileMetadata): Add field. * src/util/storage_file.c (virStorageFileGetMetadataFromBuf): (virStorageFileFreeMetadata): Manage it (absolutePathFromBaseFile): Store absolute names in canonical form.
This commit is contained in:
parent
1fc9593271
commit
82507838e0
src/util
@ -28,6 +28,7 @@
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#ifdef __linux__
|
||||
# if HAVE_LINUX_MAGIC_H
|
||||
# include <linux/magic.h>
|
||||
@ -530,18 +531,22 @@ static char *
|
||||
absolutePathFromBaseFile(const char *base_file, const char *path)
|
||||
{
|
||||
char *res;
|
||||
char *tmp;
|
||||
size_t d_len = dir_len (base_file);
|
||||
|
||||
/* If path is already absolute, or if dirname(base_file) is ".",
|
||||
just return a copy of path. */
|
||||
if (*path == '/' || d_len == 0)
|
||||
return strdup(path);
|
||||
return canonicalize_file_name(path);
|
||||
|
||||
/* Ensure that the following cast-to-int is valid. */
|
||||
if (d_len > INT_MAX)
|
||||
return NULL;
|
||||
|
||||
ignore_value(virAsprintf(&res, "%.*s/%s", (int) d_len, base_file, path));
|
||||
if (virAsprintf(&tmp, "%.*s/%s", (int) d_len, base_file, path) < 0)
|
||||
return NULL;
|
||||
res = canonicalize_file_name(tmp);
|
||||
VIR_FREE(tmp);
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -697,17 +702,23 @@ virStorageFileGetMetadataFromBuf(int format,
|
||||
|
||||
meta->backingStoreIsFile = false;
|
||||
if (backing != NULL) {
|
||||
if (virBackingStoreIsFile(backing)) {
|
||||
meta->backingStoreIsFile = true;
|
||||
meta->backingStore = absolutePathFromBaseFile(path, backing);
|
||||
} else {
|
||||
meta->backingStore = strdup(backing);
|
||||
}
|
||||
VIR_FREE(backing);
|
||||
meta->backingStore = strdup(backing);
|
||||
if (meta->backingStore == NULL) {
|
||||
virReportOOMError();
|
||||
VIR_FREE(backing);
|
||||
return -1;
|
||||
}
|
||||
if (virBackingStoreIsFile(backing)) {
|
||||
meta->backingStoreIsFile = true;
|
||||
meta->backingStoreRaw = meta->backingStore;
|
||||
meta->backingStore = absolutePathFromBaseFile(path, backing);
|
||||
if (meta->backingStore == NULL) {
|
||||
virReportOOMError();
|
||||
VIR_FREE(backing);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
VIR_FREE(backing);
|
||||
meta->backingStoreFormat = backingFormat;
|
||||
} else {
|
||||
meta->backingStore = NULL;
|
||||
@ -1014,6 +1025,7 @@ virStorageFileFreeMetadata(virStorageFileMetadata *meta)
|
||||
|
||||
virStorageFileFreeMetadata(meta->backingMeta);
|
||||
VIR_FREE(meta->backingStore);
|
||||
VIR_FREE(meta->backingStoreRaw);
|
||||
VIR_FREE(meta);
|
||||
}
|
||||
|
||||
|
@ -53,7 +53,8 @@ VIR_ENUM_DECL(virStorageFileFormat);
|
||||
typedef struct _virStorageFileMetadata virStorageFileMetadata;
|
||||
typedef virStorageFileMetadata *virStorageFileMetadataPtr;
|
||||
struct _virStorageFileMetadata {
|
||||
char *backingStore;
|
||||
char *backingStore; /* Canonical name (absolute file, or protocol) */
|
||||
char *backingStoreRaw; /* If file, original name, possibly relative */
|
||||
int backingStoreFormat; /* enum virStorageFileFormat */
|
||||
bool backingStoreIsFile;
|
||||
virStorageFileMetadataPtr backingMeta;
|
||||
|
Loading…
x
Reference in New Issue
Block a user