mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-23 21:34:54 +03:00
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 commit367cd69
(even though I accidentally removed the fixme comment early in74430fe
). * 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>
This commit is contained in:
parent
74430fe364
commit
d193b34deb
@ -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)
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user