Make virConnectClass be a child of virAbstractConnectClass and adapt all error handling functions to that. This will allow us to create new connect classes that will just work with our error reporting. Signed-off-by: Martin Kletzander <mkletzan@xxxxxxxxxx> --- src/Makefile.am | 1 + src/datatypes.c | 9 ++--- src/datatypes.h | 8 ++--- src/libvirt-host.c | 3 +- src/util/virerror.c | 94 +++++++++++++++++++++++++++++++++++++++-------------- src/util/virerror.h | 4 +-- 6 files changed, 81 insertions(+), 38 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index 5763659..6d1b4fb 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2122,6 +2122,7 @@ if WITH_LXC noinst_LTLIBRARIES += libvirt-setuid-rpc-client.la libvirt_setuid_rpc_client_la_SOURCES = \ + util/virabstracts.c \ util/viralloc.c \ util/viratomic.c \ util/viratomic.h \ diff --git a/src/datatypes.c b/src/datatypes.c index 39f83d9..b21113e 100644 --- a/src/datatypes.c +++ b/src/datatypes.c @@ -72,8 +72,10 @@ virDataTypesOnceInit(void) DECLARE_CLASS_COMMON(basename, virClassForObject()) #define DECLARE_CLASS_LOCKABLE(basename) \ DECLARE_CLASS_COMMON(basename, virClassForObjectLockable()) +#define DECLARE_CLASS_CONNECT(basename) \ + DECLARE_CLASS_COMMON(basename, virClassForAbstractConnect()) - DECLARE_CLASS_LOCKABLE(virConnect); + DECLARE_CLASS_CONNECT(virConnect); DECLARE_CLASS_LOCKABLE(virConnectCloseCallbackData); DECLARE_CLASS(virDomain); DECLARE_CLASS(virDomainSnapshot); @@ -88,6 +90,7 @@ virDataTypesOnceInit(void) #undef DECLARE_CLASS_COMMON #undef DECLARE_CLASS_LOCKABLE +#undef DECLARE_CLASS_CONNECT #undef DECLARE_CLASS return 0; @@ -110,7 +113,7 @@ virGetConnect(void) if (virDataTypesInitialize() < 0) return NULL; - if (!(ret = virObjectLockableNew(virConnectClass))) + if (!(ret = virGetAbstractConnect(virConnectClass))) return NULL; if (!(ret->closeCallback = virObjectLockableNew(virConnectCloseCallbackDataClass))) @@ -138,8 +141,6 @@ virConnectDispose(void *obj) if (conn->driver) conn->driver->connectClose(conn); - virResetError(&conn->err); - virURIFree(conn->uri); if (conn->closeCallback) { diff --git a/src/datatypes.h b/src/datatypes.h index f1d01d5..9f95811 100644 --- a/src/datatypes.h +++ b/src/datatypes.h @@ -25,6 +25,7 @@ # include "internal.h" # include "driver.h" +# include "virabstracts.h" # include "virthread.h" # include "virobject.h" # include "viruuid.h" @@ -328,7 +329,7 @@ struct _virConnectCloseCallbackData { * Internal structure associated to a connection */ struct _virConnect { - virObjectLockable object; + virAbstractConnect parent; /* All the variables from here, until declared otherwise in one of * the following comments, are setup at time of connection open @@ -359,11 +360,6 @@ struct _virConnect { * virDomain/virNetwork object associated with this connection. */ - /* Per-connection error. */ - virError err; /* the last error */ - virErrorFunc handler; /* associated handlet */ - void *userData; /* the user data */ - /* Per-connection close callback */ virConnectCloseCallbackDataPtr closeCallback; }; diff --git a/src/libvirt-host.c b/src/libvirt-host.c index 03bee1f..74d9bef 100644 --- a/src/libvirt-host.c +++ b/src/libvirt-host.c @@ -51,7 +51,8 @@ VIR_LOG_INIT("libvirt.host"); int virConnectRef(virConnectPtr conn) { - VIR_DEBUG("conn=%p refs=%d", conn, conn ? conn->object.parent.u.s.refs : 0); + VIR_DEBUG("conn=%p refs=%d", conn, + conn ? conn->parent.parent.parent.u.s.refs : 0); virResetLastError(); diff --git a/src/util/virerror.c b/src/util/virerror.c index 73dae95..8696e31 100644 --- a/src/util/virerror.c +++ b/src/util/virerror.c @@ -27,6 +27,7 @@ #include <string.h> #include <stdarg.h> +#include "virabstracts.h" #include "virerror.h" #include "datatypes.h" #include "virlog.h" @@ -421,9 +422,10 @@ virResetLastError(void) virErrorPtr virConnGetLastError(virConnectPtr conn) { - if (conn == NULL) + if (!conn) return NULL; - return &conn->err; + + return &conn->parent.err; } /** @@ -458,17 +460,38 @@ virConnCopyLastError(virConnectPtr conn, virErrorPtr to) /* We can't guarantee caller has initialized it to zero */ memset(to, 0, sizeof(*to)); - if (conn == NULL) + if (!conn) return -1; + virObjectLock(conn); - if (conn->err.code == VIR_ERR_OK) + if (conn->parent.err.code == VIR_ERR_OK) virResetError(to); else - virCopyError(&conn->err, to); + virCopyError(&conn->parent.err, to); virObjectUnlock(conn); return to->code; } +static void +virAdmConnResetLastError(void *anyobj) +{ + virAbstractConnectPtr obj = anyobj; + + if (!virObjectIsClass(obj, virClassForAbstractConnect())) { + VIR_WARN("Object %p (%s) is not a virObjectLockable instance", + obj, + obj ? virClassName(obj->parent.parent.klass) : "(unknown)"); + return; + } + + if (!obj) + return; + + virObjectLock(obj); + virResetError(&obj->err); + virObjectUnlock(obj); +} + /** * virConnResetLastError: * @conn: pointer to the hypervisor connection @@ -481,11 +504,7 @@ virConnCopyLastError(virConnectPtr conn, virErrorPtr to) void virConnResetLastError(virConnectPtr conn) { - if (conn == NULL) - return; - virObjectLock(conn); - virResetError(&conn->err); - virObjectUnlock(conn); + virAdmConnResetLastError(conn); } /** @@ -504,6 +523,28 @@ virSetErrorFunc(void *userData, virErrorFunc handler) virUserData = userData; } +static void +virAbsConnSetErrorFunc(void *anyobj, void *userData, + virErrorFunc handler) +{ + virAbstractConnectPtr obj = anyobj; + + if (!virObjectIsClass(obj, virClassForAbstractConnect())) { + VIR_WARN("Object %p (%s) is not a virObjectLockable instance", + obj, + obj ? virClassName(obj->parent.parent.klass) : "(unknown)"); + return; + } + + if (!obj) + return; + + virObjectLock(obj); + obj->handler = handler; + obj->userData = userData; + virObjectUnlock(obj); +} + /** * virConnSetErrorFunc: * @conn: pointer to the hypervisor connection @@ -518,12 +559,7 @@ void virConnSetErrorFunc(virConnectPtr conn, void *userData, virErrorFunc handler) { - if (conn == NULL) - return; - virObjectLock(conn); - conn->handler = handler; - conn->userData = userData; - virObjectUnlock(conn); + virAbsConnSetErrorFunc(conn, userData, handler); } /** @@ -574,7 +610,7 @@ virDefaultErrorFunc(virErrorPtr err) /** * virDispatchError: - * @conn: pointer to the hypervisor connection + * @anyobj: pointer to connection (be it admin or hypervisor one) * * Internal helper to do final stage of error * reporting in public APIs. @@ -584,11 +620,19 @@ virDefaultErrorFunc(virErrorPtr err) * - Invoke the error callback functions */ void -virDispatchError(virConnectPtr conn) +virDispatchError(void *anyobj) { virErrorPtr err = virLastErrorObject(); virErrorFunc handler = virErrorHandler; void *userData = virUserData; + virAbstractConnectPtr obj = anyobj; + + if (obj && !virObjectIsClass(obj, virClassForAbstractConnect())) { + VIR_WARN("Object %p (%s) is not a virObjectLockable instance", + obj, + obj ? virClassName(obj->parent.parent.klass) : "(unknown)"); + return; + } /* Can only happen on OOM. */ if (!err) @@ -599,15 +643,15 @@ virDispatchError(virConnectPtr conn) virErrorGenericFailure(err); /* Copy the global error to per-connection error if needed */ - if (conn) { - virObjectLock(conn); - virCopyError(err, &conn->err); + if (obj) { + virObjectLock(obj); + virCopyError(err, &obj->err); - if (conn->handler != NULL) { - handler = conn->handler; - userData = conn->userData; + if (obj->handler != NULL) { + handler = obj->handler; + userData = obj->userData; } - virObjectUnlock(conn); + virObjectUnlock(obj); } /* Invoke the error callback functions */ diff --git a/src/util/virerror.h b/src/util/virerror.h index ad3a946..ccaff12 100644 --- a/src/util/virerror.h +++ b/src/util/virerror.h @@ -1,7 +1,7 @@ /* * virerror.h: error handling and reporting code for libvirt * - * Copyright (C) 2006-2014 Red Hat, Inc. + * Copyright (C) 2006-2015 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -174,7 +174,7 @@ void virReportOOMErrorFull(int domcode, virRaiseErrorObject(__FILE__, __FUNCTION__, __LINE__, obj) int virSetError(virErrorPtr newerr); -void virDispatchError(virConnectPtr conn); +void virDispatchError(void *anyobj); const char *virStrerror(int theerrno, char *errBuf, size_t errBufLen); typedef int (*virErrorLogPriorityFunc)(virErrorPtr, int); -- 2.3.5 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list