From d193b34debce50c6e70efedcb45ce37f3b8ad456 Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Thu, 10 Apr 2014 21:44:45 -0600 Subject: [PATCH] conf: tweak chain lookup internals 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 --- src/util/virstoragefile.c | 50 ++++++++++++++++----------------------- tests/virstoragetest.c | 3 +-- 2 files changed, 22 insertions(+), 31 deletions(-) diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c index bc12cea14f..b7d95f99ad 100644 --- a/src/util/virstoragefile.c +++ b/src/util/virstoragefile.c @@ -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) diff --git a/tests/virstoragetest.c b/tests/virstoragetest.c index 5db3cde122..4798517cb2 100644 --- a/tests/virstoragetest.c +++ b/tests/virstoragetest.c @@ -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,