virStorageSourceChainLookup: Handle names like 'vda[4]' internally

All callers of this function called virStorageFileParseChainIndex
before. Internalize the logic of that function to prevent multiple calls
and passing around unnecessary temporary variables.

This is achieved by calling virStorageFileParseBackingStoreStr and using
it to fill the values internally.

Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
This commit is contained in:
Peter Krempa 2021-01-25 15:02:26 +01:00
parent 49c89fa70e
commit 8fd72501c8
4 changed files with 46 additions and 26 deletions

View File

@ -14412,7 +14412,6 @@ qemuDomainBlockPullCommon(virDomainObjPtr vm,
const char *jobname = NULL; const char *jobname = NULL;
virDomainDiskDefPtr disk; virDomainDiskDefPtr disk;
virStorageSourcePtr baseSource = NULL; virStorageSourcePtr baseSource = NULL;
unsigned int baseIndex = 0;
g_autofree char *basePath = NULL; g_autofree char *basePath = NULL;
g_autofree char *backingPath = NULL; g_autofree char *backingPath = NULL;
unsigned long long speed = bandwidth; unsigned long long speed = bandwidth;
@ -14448,9 +14447,8 @@ qemuDomainBlockPullCommon(virDomainObjPtr vm,
goto endjob; goto endjob;
if (base && if (base &&
(virStorageFileParseChainIndex(disk->dst, base, &baseIndex) < 0 ||
!(baseSource = virStorageSourceChainLookup(disk->src, disk->src, !(baseSource = virStorageSourceChainLookup(disk->src, disk->src,
base, baseIndex, NULL)))) base, disk->dst, NULL)))
goto endjob; goto endjob;
if (baseSource) { if (baseSource) {
@ -15465,9 +15463,7 @@ qemuDomainBlockCommit(virDomainPtr dom,
int ret = -1; int ret = -1;
virDomainDiskDefPtr disk = NULL; virDomainDiskDefPtr disk = NULL;
virStorageSourcePtr topSource; virStorageSourcePtr topSource;
unsigned int topIndex = 0;
virStorageSourcePtr baseSource = NULL; virStorageSourcePtr baseSource = NULL;
unsigned int baseIndex = 0;
virStorageSourcePtr top_parent = NULL; virStorageSourcePtr top_parent = NULL;
bool clean_access = false; bool clean_access = false;
g_autofree char *topPath = NULL; g_autofree char *topPath = NULL;
@ -15540,10 +15536,8 @@ qemuDomainBlockCommit(virDomainPtr dom,
if (!top || STREQ(top, disk->dst)) if (!top || STREQ(top, disk->dst))
topSource = disk->src; topSource = disk->src;
else if (virStorageFileParseChainIndex(disk->dst, top, &topIndex) < 0 || else if (!(topSource = virStorageSourceChainLookup(disk->src, NULL, top,
!(topSource = virStorageSourceChainLookup(disk->src, NULL, disk->dst, &top_parent)))
top, topIndex,
&top_parent)))
goto endjob; goto endjob;
if (topSource == disk->src) { if (topSource == disk->src) {
@ -15575,9 +15569,8 @@ qemuDomainBlockCommit(virDomainPtr dom,
if (!base && (flags & VIR_DOMAIN_BLOCK_COMMIT_SHALLOW)) if (!base && (flags & VIR_DOMAIN_BLOCK_COMMIT_SHALLOW))
baseSource = topSource->backingStore; baseSource = topSource->backingStore;
else if (virStorageFileParseChainIndex(disk->dst, base, &baseIndex) < 0 || else if (!(baseSource = virStorageSourceChainLookup(disk->src, topSource,
!(baseSource = virStorageSourceChainLookup(disk->src, topSource, base, disk->dst, NULL)))
base, baseIndex, NULL)))
goto endjob; goto endjob;
if ((flags & VIR_DOMAIN_BLOCK_COMMIT_SHALLOW) && if ((flags & VIR_DOMAIN_BLOCK_COMMIT_SHALLOW) &&

View File

@ -198,32 +198,59 @@ virStorageSourceGetMetadataFromFD(const char *path,
} }
/* Given a @chain, look for the backing store @name that is a backing file /**
* of @startFrom (or any member of @chain if @startFrom is NULL) and return * virStorageSourceChainLookup:
* that location within the chain. @chain must always point to the top of * @chain: chain top to look in
* the chain. Pass NULL for @name and 0 for @idx to find the base of the * @startFrom: move the starting point of @chain if non-NULL
* chain. Pass nonzero @idx to find the backing source according to its * @name: name of the file to look for in @chain
* position in the backing chain. If @parent is not NULL, set *@parent to * @diskTarget: optional disk target to validate against
* the preferred name of the parent (or to NULL if @name matches the start * @parent: Filled with parent virStorageSource of the returned value if non-NULL.
* of the chain). Since the results point within @chain, they must not be *
* independently freed. Reports an error and returns NULL if @name is not * Looks up a storage source definition corresponding to @name in @chain and
* found. * returns the corresponding virStorageSource. If @startFrom is non-NULL, the
* lookup starts from that virStorageSource.
*
* @name can be:
* - NULL: the end of the source chain is returned
* - "vda[4]": Storage source with 'id' == 4 is returned. If @diskTarget is
* non-NULL it's also validated that the part before the square
* bracket matches the requested target
* - "/path/to/file": Literal path is matched. Symlink resolution is attempted
* if the filename doesn't string-match with the path.
*/ */
virStorageSourcePtr virStorageSourcePtr
virStorageSourceChainLookup(virStorageSourcePtr chain, virStorageSourceChainLookup(virStorageSourcePtr chain,
virStorageSourcePtr startFrom, virStorageSourcePtr startFrom,
const char *name, const char *name,
unsigned int idx, const char *diskTarget,
virStorageSourcePtr *parent) virStorageSourcePtr *parent)
{ {
virStorageSourcePtr prev; virStorageSourcePtr prev;
const char *start = chain->path; const char *start = chain->path;
bool nameIsFile = virStorageSourceBackinStoreStringIsFile(name); bool nameIsFile = virStorageSourceBackinStoreStringIsFile(name);
g_autofree char *target = NULL;
unsigned int idx = 0;
if (diskTarget)
start = diskTarget;
if (!parent) if (!parent)
parent = &prev; parent = &prev;
*parent = NULL; *parent = NULL;
/* parse the "vda[4]" type string */
if (name &&
virStorageFileParseBackingStoreStr(name, &target, &idx) == 0) {
if (diskTarget &&
idx != 0 &&
STRNEQ(diskTarget, target)) {
virReportError(VIR_ERR_INVALID_ARG,
_("requested target '%s' does not match target '%s'"),
target, diskTarget);
return NULL;
}
}
if (startFrom) { if (startFrom) {
while (virStorageSourceIsBacking(chain) && while (virStorageSourceIsBacking(chain) &&
chain != startFrom->backingStore) chain != startFrom->backingStore)

View File

@ -43,7 +43,7 @@ virStorageSourcePtr
virStorageSourceChainLookup(virStorageSourcePtr chain, virStorageSourceChainLookup(virStorageSourcePtr chain,
virStorageSourcePtr startFrom, virStorageSourcePtr startFrom,
const char *name, const char *name,
unsigned int idx, const char *diskTarget,
virStorageSourcePtr *parent) virStorageSourcePtr *parent)
ATTRIBUTE_NONNULL(1); ATTRIBUTE_NONNULL(1);

View File

@ -366,7 +366,7 @@ testStorageLookup(const void *args)
} }
result = virStorageSourceChainLookup(data->chain, data->from, result = virStorageSourceChainLookup(data->chain, data->from,
data->name, idx, &actualParent); data->name, data->target, &actualParent);
if (!data->expResult) if (!data->expResult)
virResetLastError(); virResetLastError();