]> xenbits.xensource.com Git - libvirt.git/commitdiff
storage: remember relative names in backing chain
authorEric Blake <eblake@redhat.com>
Tue, 9 Oct 2012 23:47:42 +0000 (17:47 -0600)
committerEric Blake <eblake@redhat.com>
Fri, 19 Oct 2012 23:35:10 +0000 (17:35 -0600)
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
src/util/storage_file.h

index 76079bb8e7173b57a449e125afd9d5d5620a4a51..2ff444c03bca92fe6049115983214fc67172b73e 100644 (file)
@@ -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);
 }
 
index 9a60451075d9cd0be598ad821241fdfbffff6cf7..685fcb84610e7310824eefd7a88eff77e766a945 100644 (file)
@@ -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;