[PATCH] Make virConnectOpenInternal() report error in all cases
Michal Prívozník
mprivozn at redhat.com
Thu Jan 6 15:14:47 UTC 2022
On 1/6/22 16:04, Ani Sinha wrote:
> virConnectOpenInternal() does not report error in all failure scenarios, except
> in some specific cases. This inconsistent behavior forces the caller of this
> function report a generic error for all failure modes which then hides specific
> error scenarios. This change makes virConnectOpenInternal() report failure in
> all cases so that it can generate specific errors based on the type of failure
> encountered. The reporiting of the errors can be made more fine grained in
> subsequent changes.
>
> Signed-off-by: Ani Sinha <ani at anisinha.ca>
> ---
> src/libvirt.c | 24 ++++++++++++++++--------
> src/libxl/libxl_migration.c | 3 ---
> src/qemu/qemu_migration.c | 3 ---
> 3 files changed, 16 insertions(+), 14 deletions(-)
>
> diff --git a/src/libvirt.c b/src/libvirt.c
> index 45315f484c..53ceee1359 100644
> --- a/src/libvirt.c
> +++ b/src/libvirt.c
> @@ -893,8 +893,12 @@ virConnectOpenInternal(const char *name,
> bool embed = false;
>
> ret = virGetConnect();
> - if (ret == NULL)
> + if (ret == NULL) {
> + virReportError(VIR_ERR_INVALID_CONN,
> + _("Failed to create connection object for URI %s"),
> + NULLSTR(name));
> return NULL;
> + }
This overwrites an error reported by virGetConnect().
>
> if (virConfLoadConfig(&conf, "libvirt.conf") < 0)
> goto failed;
> @@ -974,7 +978,7 @@ virConnectOpenInternal(const char *name,
> virReportError(VIR_ERR_NO_CONNECT,
> _("URI '%s' does not include a driver name"),
> name);
> - goto failed;
> + goto failed_no_report;
I'm not a big fan of this label. But, there's an easy trick to avoid it.
So what's happening under 'failed' label is:
virReportError(VIR_ERR_OPERATION_FAILED,
_("Failed to connect to remote libvirt URI %s"),
NULLSTR(uristr));
VIR_FREE(uristr);
virObjectUnref(ret);
and we want to avoid virReportError() but do execute VIR_FREE() and
virObjectUnref(). Well, both these can be replaced with g_auto* and thus
'failed_no_report' would effectively be just plain 'return NULL'.
> }
>
> if (virConnectCheckURIMissingSlash(uristr,
> @@ -992,7 +996,7 @@ virConnectOpenInternal(const char *name,
> virReportError(VIR_ERR_NO_CONNECT,
> _("URI scheme '%s' for embedded driver is not valid"),
> ret->uri->scheme);
> - goto failed;
> + goto failed_no_report;
> }
>
> root = virURIGetParam(ret->uri, "root");
> @@ -1002,7 +1006,7 @@ virConnectOpenInternal(const char *name,
> if (!g_path_is_absolute(root)) {
> virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
> _("root path must be absolute"));
> - goto failed;
> + goto failed_no_report;
> }
>
> if (virEventRequireImpl() < 0)
> @@ -1062,7 +1066,7 @@ virConnectOpenInternal(const char *name,
> __FILE__, __FUNCTION__, __LINE__,
> _("libvirt was built without the '%s' driver"),
> ret->uri->scheme);
> - goto failed;
> + goto failed_no_report;
> }
>
> VIR_DEBUG("trying driver %zu (%s) ...",
> @@ -1112,13 +1116,13 @@ virConnectOpenInternal(const char *name,
> virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
> _("Driver %s cannot be used in embedded mode"),
> virConnectDriverTab[i]->hypervisorDriver->name);
> - goto failed;
> + goto failed_no_report;
> }
> /* before starting the new connection, check if the driver only works
> * with a server, and so return an error if the server is missing */
> if (virConnectDriverTab[i]->remoteOnly && ret->uri && !ret->uri->server) {
> virReportError(VIR_ERR_INVALID_ARG, "%s", _("URI is missing the server part"));
> - goto failed;
> + goto failed_no_report;
> }
>
> ret->driver = virConnectDriverTab[i]->hypervisorDriver;
> @@ -1155,7 +1159,7 @@ virConnectOpenInternal(const char *name,
> if (!ret->driver) {
> /* If we reach here, then all drivers declined the connection. */
> virReportError(VIR_ERR_NO_CONNECT, "%s", NULLSTR(name));
> - goto failed;
> + goto failed_no_report;
> }
>
> VIR_FREE(uristr);
> @@ -1163,6 +1167,10 @@ virConnectOpenInternal(const char *name,
> return ret;
>
> failed:
> + virReportError(VIR_ERR_OPERATION_FAILED,
> + _("Failed to connect to remote libvirt URI %s"),
> + NULLSTR(uristr));
> + failed_no_report:
> VIR_FREE(uristr);
> virObjectUnref(ret);
>
> diff --git a/src/libxl/libxl_migration.c b/src/libxl/libxl_migration.c
> index 6d0ab4ee28..bc2b5401da 100644
> --- a/src/libxl/libxl_migration.c
> +++ b/src/libxl/libxl_migration.c
> @@ -1134,9 +1134,6 @@ libxlDomainMigrationSrcPerformP2P(libxlDriverPrivate *driver,
> virObjectLock(vm);
>
> if (dconn == NULL) {
> - virReportError(VIR_ERR_OPERATION_FAILED,
> - _("Failed to connect to remote libvirt URI %s: %s"),
> - dconnuri, virGetLastErrorMessage());
This change and the other hunk below should be a separate commit, IMO.
> return ret;
> }
>
> diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
> index b9d7d582f5..2635ef1162 100644
> --- a/src/qemu/qemu_migration.c
> +++ b/src/qemu/qemu_migration.c
> @@ -5145,9 +5145,6 @@ qemuMigrationSrcPerformPeer2Peer(virQEMUDriver *driver,
> goto cleanup;
>
> if (dconn == NULL) {
> - virReportError(VIR_ERR_OPERATION_FAILED,
> - _("Failed to connect to remote libvirt URI %s: %s"),
> - dconnuri, virGetLastErrorMessage());
> return -1;
> }
>
Michal
More information about the libvir-list
mailing list