[libvirt] [PATCH 1/5] Add public API to register a callback to be invoked on connection close

Daniel P. Berrange berrange at redhat.com
Thu Jul 19 15:04:36 UTC 2012


From: "Daniel P. Berrange" <berrange at redhat.com>

Define a new virConnectSetCloseCallback() public API which allows
registering a callback to be invoked when the connection to a
hypervisor is closed. The callback is provided with the reason for
the close, which may be 'error', 'eof' or 'keepalive'.

Signed-off-by: Daniel P. Berrange <berrange at redhat.com>
---
 include/libvirt/libvirt.h.in |   40 +++++++++++++++++++++++--------
 src/datatypes.c              |    4 ++++
 src/datatypes.h              |    5 ++++
 src/libvirt.c                |   53 ++++++++++++++++++++++++++++++++++++++++++
 src/libvirt_public.syms      |    6 +++++
 5 files changed, 98 insertions(+), 10 deletions(-)

diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index e34438c..74b3f90 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -49,6 +49,17 @@ extern "C" {
  * defines VIR_ENUM_SENTINELS.  Enumerations for bit values do not
  * have a *_LAST value, but additional bits may be defined.  */
 
+/*
+ * virFreeCallback:
+ * @opaque: opaque user data provided at registration
+ *
+ * Type for a domain event callback when the event is deregistered and
+ * need to be freed, @opaque is provided along with the callback at
+ * registration time
+ */
+typedef void (*virFreeCallback)(void *opaque);
+
+
 /**
  * virConnect:
  *
@@ -1148,6 +1159,25 @@ int virConnectSetKeepAlive(virConnectPtr conn,
                            int interval,
                            unsigned int count);
 
+typedef enum {
+    VIR_CONNECT_CLOSE_REASON_ERROR     = 1, /* Misc I/O error */
+    VIR_CONNECT_CLOSE_REASON_EOF       = 2, /* End-of-file from server */
+    VIR_CONNECT_CLOSE_REASON_KEEPALIVE = 3, /* Keepalive timer triggered */
+    VIR_CONNECT_CLOSE_REASON_CLIENT    = 4, /* Client requested it */
+
+# ifdef VIR_ENUM_SENTINELS
+    VIR_CONNECT_CLOSE_REASON_LAST
+# endif
+} virConnectCloseReason;
+
+typedef void (*virConnectCloseFunc)(virConnectPtr conn,
+                                    int reason,
+                                    void *opaque);
+
+int virConnectSetCloseCallback(virConnectPtr conn,
+                               virConnectCloseFunc cb,
+                               void *opaque,
+                               virFreeCallback freecb);
 
 /*
  * Capabilities of the connection / driver.
@@ -2861,16 +2891,6 @@ typedef int (*virConnectDomainEventCallback)(virConnectPtr conn,
                                              int detail,
                                              void *opaque);
 
-/*
- * virFreeCallback:
- * @opaque: opaque user data provided at registration
- *
- * Type for a domain event callback when the event is deregistered and
- * need to be freed, @opaque is provided along with the callback at
- * registration time
- */
-typedef void (*virFreeCallback)(void *opaque);
-
 int virConnectDomainEventRegister(virConnectPtr conn,
                                   virConnectDomainEventCallback cb,
                                   void *opaque,
diff --git a/src/datatypes.c b/src/datatypes.c
index d718170..5d415b8 100644
--- a/src/datatypes.c
+++ b/src/datatypes.c
@@ -115,6 +115,10 @@ virReleaseConnect(virConnectPtr conn) {
 
     virMutexLock(&conn->lock);
 
+    if (conn->closeOpaque &&
+        conn->closeFreeCallback)
+        conn->closeFreeCallback(conn->closeOpaque);
+
     virResetError(&conn->err);
 
     virURIFree(conn->uri);
diff --git a/src/datatypes.h b/src/datatypes.h
index fc284d2..af054ac 100644
--- a/src/datatypes.h
+++ b/src/datatypes.h
@@ -187,6 +187,11 @@ struct _virConnect {
     virErrorFunc handler;   /* associated handlet */
     void *userData;         /* the user data */
 
+    /* Per-connection close callback */
+    virConnectCloseFunc closeCallback;
+    void *closeOpaque;
+    virFreeCallback closeFreeCallback;
+
     int refs;                 /* reference count */
 };
 
diff --git a/src/libvirt.c b/src/libvirt.c
index df78e8a..8acb87f 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -18613,6 +18613,59 @@ error:
 
 
 /**
+ * virConnectSetCloseCallback:
+ * @conn: pointer to connection object
+ * @cb: callback to invoke upon close
+ * @opaque: user data to pass to @cb
+ * @freecb: callback to free @opaque
+ *
+ * Registers a callback to be invoked when the connection
+ * is closed. This callback is invoked when there is any
+ * condition that causes the socket connection to the
+ * hypervisor to be closed. 
+ *
+ * This function is only applicable to hypervisor drivers
+ * which maintain a persistent open connection. Drivers
+ * which open a new connection for every operation will
+ * not invoke this.
+ *
+ * The @freecb must not invoke any other libvirt public
+ * APIs, since it is not called from a re-entrant safe
+ * context.
+ *
+ * Returns 0 on success, -1 on error
+ */
+int virConnectSetCloseCallback(virConnectPtr conn,
+                               virConnectCloseFunc cb,
+                               void *opaque,
+                               virFreeCallback freecb)
+{
+    VIR_DEBUG("conn=%p", conn);
+
+    virResetLastError();
+
+    if (!VIR_IS_CONNECT(conn)) {
+        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
+        virDispatchError(NULL);
+        return -1;
+    }
+
+    virMutexLock(&conn->lock);
+
+    if (conn->closeOpaque &&
+        conn->closeFreeCallback)
+        conn->closeFreeCallback(conn->closeOpaque);
+
+    conn->closeCallback = cb;
+    conn->closeOpaque = opaque;
+    conn->closeFreeCallback = freecb;
+
+    virMutexUnlock(&conn->lock);
+
+    return 0;
+}
+
+/**
  * virDomainSetBlockIoTune:
  * @dom: pointer to domain object
  * @disk: path to the block device, or device shorthand
diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
index 2913a81..dab8725 100644
--- a/src/libvirt_public.syms
+++ b/src/libvirt_public.syms
@@ -544,4 +544,10 @@ LIBVIRT_0.9.13 {
         virDomainSnapshotRef;
 } LIBVIRT_0.9.11;
 
+
+LIBVIRT_0.9.14 {
+    global:
+        virConnectSetCloseCallback;
+} LIBVIRT_0.9.13;
+
 # .... define new API here using predicted next version number ....
-- 
1.7.10.4




More information about the libvir-list mailing list