[libvirt] [PATCH 3/6] conf: report error on chain lookup failure
John Ferlan
jferlan at redhat.com
Fri Apr 11 19:12:26 UTC 2014
On 04/11/2014 12:21 AM, Eric Blake wrote:
> The chain lookup function was inconsistent on whether it left
> a message in the log when looking up a name that is not found
> on the chain (leaving a message for OOM or if name was
> relative but not part of the chain), and could litter the log
> even when successful (when name was relative but deep in the
> chain, use of virFindBackingFile early in the chain would complain
> about a file not found). It's easier to make the function
> consistently emit a message exactly once on failure, and to let
> all callers rely on the clean semantics.
>
> * src/util/virstoragefile.c (virStorageFileChainLookup): Always
> report error on failure. Simplify relative lookups.
> * src/qemu/qemu_driver.c (qemuDomainBlockCommit): Avoid
> overwriting error.
>
> Signed-off-by: Eric Blake <eblake at redhat.com>
> ---
> src/qemu/qemu_driver.c | 10 +---------
> src/util/virstoragefile.c | 17 +++++++++--------
> 2 files changed, 10 insertions(+), 17 deletions(-)
>
> diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
> index b0c6a74..b8cfe27 100644
> --- a/src/qemu/qemu_driver.c
> +++ b/src/qemu/qemu_driver.c
> @@ -15346,9 +15346,6 @@ qemuDomainBlockCommit(virDomainPtr dom, const char *path, const char *base,
> disk->src.path,
> top, &top_meta,
> &top_parent))) {
> - virReportError(VIR_ERR_INVALID_ARG,
> - _("could not find top '%s' in chain for '%s'"),
> - top, path);
> goto endjob;
> }
> if (!top_meta || !top_meta->backingStore) {
> @@ -15360,13 +15357,8 @@ qemuDomainBlockCommit(virDomainPtr dom, const char *path, const char *base,
> if (!base && (flags & VIR_DOMAIN_BLOCK_COMMIT_SHALLOW)) {
> base_canon = top_meta->backingStore;
> } else if (!(base_canon = virStorageFileChainLookup(top_meta, top_canon,
> - base, NULL, NULL))) {
> - virReportError(VIR_ERR_INVALID_ARG,
> - _("could not find base '%s' below '%s' in chain "
> - "for '%s'"),
> - base ? base : "(default)", top_canon, path);
> + base, NULL, NULL)))
> goto endjob;
> - }
Does removal of {} violate the one line "rule of thumb"... In either
case the "if" portion should be made consistent as well as this now has
if (xxx) {
oneline
} else
onelonglinebecauseofarguments
Probably would be nice to have an extra line after endjob; and before
following comment - just a readability thing for me at least.
> /* Note that this code exploits the fact that
> * virStorageFileChainLookup guarantees a simple pointer
> * comparison will work, rather than needing full-blown STREQ. */
> diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
> index 2013914..66a6ab1 100644
> --- a/src/util/virstoragefile.c
> +++ b/src/util/virstoragefile.c
> @@ -1537,7 +1537,8 @@ int virStorageFileGetSCSIKey(const char *path,
> * backing element is not a file). If PARENT is not NULL, set *PARENT
> * to the preferred name of the parent (or to NULL if NAME matches
> * START). Since the results point within CHAIN, they must not be
> - * independently freed. */
> + * independently freed. Reports an error and returns NULL if NAME is
> + * not found. */
> const char *
> virStorageFileChainLookup(virStorageFileMetadataPtr chain, const char *start,
> const char *name, virStorageFileMetadataPtr *meta,
> @@ -1570,15 +1571,12 @@ virStorageFileChainLookup(virStorageFileMetadataPtr chain, const char *start,
> STREQ(name, owner->backingStore)) {
> break;
> } else if (virStorageIsFile(owner->backingStore)) {
> - char *absName = NULL;
> - if (virFindBackingFile(owner->directory, name,
> - NULL, &absName) < 0)
> + int result = virFileRelLinkPointsTo(owner->directory, name,
> + owner->backingStore);
> + if (result < 0)
> goto error;
> - if (absName && STREQ(absName, owner->backingStore)) {
> - VIR_FREE(absName);
> + if (result > 0)
> break;
> - }
> - VIR_FREE(absName);
> }
> *parent = owner->backingStore;
> owner = owner->backingMeta;
> @@ -1590,6 +1588,9 @@ virStorageFileChainLookup(virStorageFileMetadataPtr chain, const char *start,
> return owner->backingStore;
>
> error:
> + virReportError(VIR_ERR_INVALID_ARG,
> + _("could not find image '%s' in chain for '%s'"),
> + name, start);
Looking at the context of the code expanded out a bit... there's a few
checks for !name = can we get here with name == NULL? Looking ahead to
patch 4 this will be more important...
> *parent = NULL;
> if (meta)
> *meta = NULL;
>
ACK - seems reasonable, just address the possible NULL name...
John
More information about the libvir-list
mailing list