mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-28 07:25:17 +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
@ -28,6 +28,7 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
# if HAVE_LINUX_MAGIC_H
|
# if HAVE_LINUX_MAGIC_H
|
||||||
# include <linux/magic.h>
|
# include <linux/magic.h>
|
||||||
@ -530,18 +531,22 @@ static char *
|
|||||||
absolutePathFromBaseFile(const char *base_file, const char *path)
|
absolutePathFromBaseFile(const char *base_file, const char *path)
|
||||||
{
|
{
|
||||||
char *res;
|
char *res;
|
||||||
|
char *tmp;
|
||||||
size_t d_len = dir_len (base_file);
|
size_t d_len = dir_len (base_file);
|
||||||
|
|
||||||
/* If path is already absolute, or if dirname(base_file) is ".",
|
/* If path is already absolute, or if dirname(base_file) is ".",
|
||||||
just return a copy of path. */
|
just return a copy of path. */
|
||||||
if (*path == '/' || d_len == 0)
|
if (*path == '/' || d_len == 0)
|
||||||
return strdup(path);
|
return canonicalize_file_name(path);
|
||||||
|
|
||||||
/* Ensure that the following cast-to-int is valid. */
|
/* Ensure that the following cast-to-int is valid. */
|
||||||
if (d_len > INT_MAX)
|
if (d_len > INT_MAX)
|
||||||
return NULL;
|
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;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -697,17 +702,23 @@ virStorageFileGetMetadataFromBuf(int format,
|
|||||||
|
|
||||||
meta->backingStoreIsFile = false;
|
meta->backingStoreIsFile = false;
|
||||||
if (backing != NULL) {
|
if (backing != NULL) {
|
||||||
if (virBackingStoreIsFile(backing)) {
|
|
||||||
meta->backingStoreIsFile = true;
|
|
||||||
meta->backingStore = absolutePathFromBaseFile(path, backing);
|
|
||||||
} else {
|
|
||||||
meta->backingStore = strdup(backing);
|
meta->backingStore = strdup(backing);
|
||||||
}
|
|
||||||
VIR_FREE(backing);
|
|
||||||
if (meta->backingStore == NULL) {
|
if (meta->backingStore == NULL) {
|
||||||
virReportOOMError();
|
virReportOOMError();
|
||||||
|
VIR_FREE(backing);
|
||||||
return -1;
|
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;
|
meta->backingStoreFormat = backingFormat;
|
||||||
} else {
|
} else {
|
||||||
meta->backingStore = NULL;
|
meta->backingStore = NULL;
|
||||||
@ -1014,6 +1025,7 @@ virStorageFileFreeMetadata(virStorageFileMetadata *meta)
|
|||||||
|
|
||||||
virStorageFileFreeMetadata(meta->backingMeta);
|
virStorageFileFreeMetadata(meta->backingMeta);
|
||||||
VIR_FREE(meta->backingStore);
|
VIR_FREE(meta->backingStore);
|
||||||
|
VIR_FREE(meta->backingStoreRaw);
|
||||||
VIR_FREE(meta);
|
VIR_FREE(meta);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,7 +53,8 @@ VIR_ENUM_DECL(virStorageFileFormat);
|
|||||||
typedef struct _virStorageFileMetadata virStorageFileMetadata;
|
typedef struct _virStorageFileMetadata virStorageFileMetadata;
|
||||||
typedef virStorageFileMetadata *virStorageFileMetadataPtr;
|
typedef virStorageFileMetadata *virStorageFileMetadataPtr;
|
||||||
struct _virStorageFileMetadata {
|
struct _virStorageFileMetadata {
|
||||||
char *backingStore;
|
char *backingStore; /* Canonical name (absolute file, or protocol) */
|
||||||
|
char *backingStoreRaw; /* If file, original name, possibly relative */
|
||||||
int backingStoreFormat; /* enum virStorageFileFormat */
|
int backingStoreFormat; /* enum virStorageFileFormat */
|
||||||
bool backingStoreIsFile;
|
bool backingStoreIsFile;
|
||||||
virStorageFileMetadataPtr backingMeta;
|
virStorageFileMetadataPtr backingMeta;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user