[libvirt] [PATCH 03/15] datatypes: Use abstract connect class in virConnect

Martin Kletzander mkletzan at redhat.com
Thu Apr 16 14:46:38 UTC 2015


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 at 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




More information about the libvir-list mailing list