]> xenbits.xensource.com Git - libvirt.git/commitdiff
conf: tweak chain lookup internals
authorEric Blake <eblake@redhat.com>
Fri, 11 Apr 2014 03:44:45 +0000 (21:44 -0600)
committerEric Blake <eblake@redhat.com>
Sat, 12 Apr 2014 13:16:03 +0000 (07:16 -0600)
Thanks to the testsuite, I feel quite confident that this rewrite
is correct; it gives the same results for all cases except for one.
I can make the argument that _that_ case was a pre-existing bug:
when looking up relative names, the lookup is supposed to be
pegged to the directory that contains the parent qcow2 file.  Thus,
this resolves the fixme first mentioned in commit 367cd69 (even
though I accidentally removed the fixme comment early in 74430fe).

* src/util/virstoragefile.c (virStorageFileChainLookup): Depend on
new rather than old fields.
* tests/virstoragetest.c (mymain): Adjust test to match fix.

Signed-off-by: Eric Blake <eblake@redhat.com>
src/util/virstoragefile.c
tests/virstoragetest.c

index bc12cea14ff255e8633f461d72284ca7baf95020..b7d95f99ad433997b6c353089f05a0f4e48352cf 100644 (file)
@@ -1544,48 +1544,40 @@ virStorageFileChainLookup(virStorageFileMetadataPtr chain,
                           const char **parent)
 {
     const char *start = chain->canonPath;
-    virStorageFileMetadataPtr owner;
     const char *tmp;
+    const char *parentDir = ".";
+    bool nameIsFile = virStorageIsFile(name);
 
     if (!parent)
         parent = &tmp;
 
     *parent = NULL;
-    if (name ? STREQ(start, name) || virFileLinkPointsTo(start, name) :
-        !chain->backingStore) {
-        if (meta)
-            *meta = chain;
-        return start;
-    }
-
-    owner = chain;
-    *parent = start;
-    while (owner) {
-        if (!owner->backingStore)
-            goto error;
+    while (chain) {
         if (!name) {
-            if (!owner->backingMeta ||
-                !owner->backingMeta->backingStore)
+            if (!chain->backingMeta)
                 break;
-        } else if (STREQ_NULLABLE(name, owner->backingStoreRaw) ||
-                   STREQ(name, owner->backingStore)) {
-            break;
-        } else if (virStorageIsFile(owner->backingStore)) {
-            int result = virFileRelLinkPointsTo(owner->directory, name,
-                                                owner->backingStore);
-            if (result < 0)
-                goto error;
-            if (result > 0)
+        } else {
+            if (STREQ(name, chain->path))
                 break;
+            if (nameIsFile && (chain->type == VIR_STORAGE_TYPE_FILE ||
+                               chain->type == VIR_STORAGE_TYPE_BLOCK)) {
+                int result = virFileRelLinkPointsTo(parentDir, name,
+                                                    chain->canonPath);
+                if (result < 0)
+                    goto error;
+                if (result > 0)
+                    break;
+            }
         }
-        *parent = owner->backingStore;
-        owner = owner->backingMeta;
+        *parent = chain->canonPath;
+        parentDir = chain->relDir;
+        chain = chain->backingMeta;
     }
-    if (!owner)
+    if (!chain)
         goto error;
     if (meta)
-        *meta = owner->backingMeta;
-    return owner->backingStore;
+        *meta = chain;
+    return chain->canonPath;
 
  error:
     if (name)
index 5db3cde122b4fdc7b8214f2c92f5f695a5fe5680..4798517cb29b1d106b663d693f13d17042107266 100644 (file)
@@ -935,8 +935,7 @@ mymain(void)
     TEST_LOOKUP(19, abswrap, chain->canonPath, chain, NULL);
     TEST_LOOKUP(20, "../qcow2", chain->backingStore, chain->backingMeta,
                 chain->canonPath);
-    TEST_LOOKUP(21, "qcow2", chain->backingStore, chain->backingMeta,
-                chain->canonPath);
+    TEST_LOOKUP(21, "qcow2", NULL, NULL, NULL);
     TEST_LOOKUP(22, absqcow2, chain->backingStore, chain->backingMeta,
                 chain->canonPath);
     TEST_LOOKUP(23, "raw", chain->backingMeta->backingStore,