On 23.09.2020 22:50, Jiri Denemark wrote:
On Mon, Sep 21, 2020 at 10:51:16 +0300, Nikolay Shirokovskiy wrote:
> Currently virDomainMigrate3 reports "this function is not supported by the
> connection driver: virDomainMigrate3" if connection to destination for example
> is broken. This is a bit misleading.
>
> This is a result of we treat errors as unsupported feature in
> VIR_DRV_SUPPORTS_FEATURE macro. So let's handle errors instead. In order to
> keep logic clean as before there are new helper functions
> virDrvSupportsFeature/virDrvNSupportsFeature. They allow to keep if/else if
> structure of feature tests.
>
> I guess all the other occurences of VIR_DRV_SUPPORTS_FEATURE need to be
> replaced with one these new helper functions so that we detect error early and
> not have issues similar to virDomainMigrate3. I'm going to fix the other
> places if this RFC is approved.
To be honest, I think this is quite ugly.
>
> ---
> src/datatypes.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++
> src/datatypes.h | 7 +++++
> src/libvirt-domain.c | 76 +++++++++++++++++++++++++++++++---------------------
> 3 files changed, 123 insertions(+), 30 deletions(-)
>
> diff --git a/src/datatypes.c b/src/datatypes.c
> index 1db38c5..3fb71f4 100644
> --- a/src/datatypes.c
> +++ b/src/datatypes.c
> @@ -1257,3 +1257,73 @@ virAdmClientDispose(void *obj)
>
> virObjectUnref(clt->srv);
> }
> +
> +
> +/*
> + * Tests if feature is supported by connection. If testing failed
> + * due to error then function returns true as well and set @err flag
> + * to true. Thus positive result should be checked for an error.
> + * If @err is already set to true then no checking is done and
> + * the function returns true immediately so that previous error
> + * is not overwritten.
> + *
> + * Returns:
> + * true feature is supported or testing hit error
> + * false feature is not supported
> + */
> +bool
> +virDrvSupportsFeature(virConnectPtr conn,
> + virDrvFeature feature,
> + bool *err)
> +{
> + int rc;
> +
> + if (*err)
> + return true;
> +
> + if (!conn->driver->connectSupportsFeature)
> + return false;
> +
> + if ((rc = conn->driver->connectSupportsFeature(conn, feature)) < 0) {
> + *err = true;
> + return true;
> + }
> +
> + return rc > 0 ? true : false;
> +}
I would just make virDrvSupportsFeature a tiny wrapper around
conn->driver->connectSupportsFeature checking
conn->driver->connectSupportsFeature != NULL and that's it. It could
break the if/elseif flow, but with much cleaner semantics and reduced
black magic.
Ok, thanx. I'll send next version.
Nikolay