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(a)redhat.com>
---
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