On 10/17/2012 06:30 PM, Eric Blake wrote: > 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. > --- > src/util/storage_file.c | 28 ++++++++++++++++++++-------- > src/util/storage_file.h | 3 ++- > 2 files changed, 22 insertions(+), 9 deletions(-) > > diff --git a/src/util/storage_file.c b/src/util/storage_file.c > index 76079bb..2ff444c 100644 > --- a/src/util/storage_file.c > +++ b/src/util/storage_file.c > @@ -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) { > + 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); > - } else { > - meta->backingStore = strdup(backing); > + if (meta->backingStore == NULL) { > + virReportOOMError(); > + VIR_FREE(backing); > + return -1; > + } > } > VIR_FREE(backing); > - if (meta->backingStore == NULL) { > - virReportOOMError(); > - return -1; > - } > 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); > } > > diff --git a/src/util/storage_file.h b/src/util/storage_file.h > index 9a60451..685fcb8 100644 > --- a/src/util/storage_file.h > +++ b/src/util/storage_file.h > @@ -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; Previous ACK stands. -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list