[libvirt] [PATCH v2 3/3] vz: implement connection close notification

nshirokovskiy at virtuozzo.com nshirokovskiy at virtuozzo.com
Thu Jun 25 11:31:43 UTC 2015


From: Nikolay Shirokovskiy <nshirokovskiy at virtuozzo.com>

Reuse virConnectCloseCallback to implement connection close event functions.
This way we automatically meet multi-thread requirements on unregistering/notification.
---
 src/vz/vz_driver.c |   26 ++++++++++++++++++++++++++
 src/vz/vz_sdk.c    |   29 +++++++++++++++++++++++++++++
 src/vz/vz_utils.h  |    3 +++
 3 files changed, 58 insertions(+), 0 deletions(-)

diff --git a/src/vz/vz_driver.c b/src/vz/vz_driver.c
index d9ddd4f..e3d0fdc 100644
--- a/src/vz/vz_driver.c
+++ b/src/vz/vz_driver.c
@@ -268,6 +268,9 @@ vzOpenDefault(virConnectPtr conn)
     if (prlsdkSubscribeToPCSEvents(privconn))
         goto error;
 
+    if (!(privconn->closeCallback = virGetConnectCloseCallback()))
+        goto error;
+
     conn->privateData = privconn;
 
     if (prlsdkLoadDomains(privconn))
@@ -276,6 +279,8 @@ vzOpenDefault(virConnectPtr conn)
     return VIR_DRV_OPEN_SUCCESS;
 
  error:
+    virObjectUnref(privconn->closeCallback);
+    privconn->closeCallback = NULL;
     virObjectUnref(privconn->domains);
     virObjectUnref(privconn->caps);
     virStoragePoolObjListFree(&privconn->pools);
@@ -350,6 +355,8 @@ vzConnectClose(virConnectPtr conn)
     virObjectUnref(privconn->caps);
     virObjectUnref(privconn->xmlopt);
     virObjectUnref(privconn->domains);
+    virObjectUnref(privconn->closeCallback);
+    privconn->closeCallback = NULL;
     virObjectEventStateFree(privconn->domainEventState);
     prlsdkDisconnect(privconn);
     conn->privateData = NULL;
@@ -1337,6 +1344,23 @@ vzDomainBlockStatsFlags(virDomainPtr domain,
     return ret;
 }
 
+static int
+vzConnectRegisterCloseCallback(virConnectPtr conn,
+                               virConnectCloseFunc cb,
+                               void *opaque,
+                               virFreeCallback freecb)
+{
+    vzConnPtr privconn = conn->privateData;
+    return virConnectCloseCallbackRegister(privconn->closeCallback, conn, cb, opaque, freecb);
+}
+
+static int
+vzConnectUnregisterCloseCallback(virConnectPtr conn, virConnectCloseFunc cb ATTRIBUTE_UNUSED)
+{
+    vzConnPtr privconn = conn->privateData;
+    virConnectCloseCallbackUnregister(privconn->closeCallback);
+    return 0;
+}
 
 static virHypervisorDriver vzDriver = {
     .name = "vz",
@@ -1389,6 +1413,8 @@ static virHypervisorDriver vzDriver = {
     .domainGetMaxMemory = vzDomainGetMaxMemory, /* 1.2.15 */
     .domainBlockStats = vzDomainBlockStats, /* 1.3.0 */
     .domainBlockStatsFlags = vzDomainBlockStatsFlags, /* 1.3.0 */
+    .connectRegisterCloseCallback = vzConnectRegisterCloseCallback, /* 1.3.0 */
+    .connectUnregisterCloseCallback = vzConnectUnregisterCloseCallback, /* 1.3.0 */
 };
 
 static virConnectDriver vzConnectDriver = {
diff --git a/src/vz/vz_sdk.c b/src/vz/vz_sdk.c
index 388ea19..5f38709 100644
--- a/src/vz/vz_sdk.c
+++ b/src/vz/vz_sdk.c
@@ -1745,6 +1745,32 @@ prlsdkHandleVmEvent(vzConnPtr privconn, PRL_HANDLE prlEvent)
     return;
 }
 
+static
+void prlsdkHandleDispatcherConnectionClosed(vzConnPtr privconn)
+{
+    virConnectCloseCallbackCall(privconn->closeCallback, VIR_CONNECT_CLOSE_REASON_EOF);
+}
+
+static void
+prlsdkHandleDispatcherEvent(vzConnPtr privconn, PRL_HANDLE prlEvent)
+{
+    PRL_RESULT pret = PRL_ERR_FAILURE;
+    PRL_EVENT_TYPE prlEventType;
+
+    pret = PrlEvent_GetType(prlEvent, &prlEventType);
+    prlsdkCheckRetGoto(pret, error);
+
+    switch (prlEventType) {
+    case PET_DSP_EVT_DISP_CONNECTION_CLOSED:
+        prlsdkHandleDispatcherConnectionClosed(privconn);
+        break;
+    default:
+        VIR_DEBUG("Skipping dispatcher event of type %d", prlEventType);
+    }
+ error:
+    return;
+}
+
 static PRL_RESULT
 prlsdkEventsHandler(PRL_HANDLE prlEvent, PRL_VOID_PTR opaque)
 {
@@ -1772,6 +1798,9 @@ prlsdkEventsHandler(PRL_HANDLE prlEvent, PRL_VOID_PTR opaque)
             // above function takes own of event
             prlEvent = PRL_INVALID_HANDLE;
             break;
+        case PIE_DISPATCHER:
+            prlsdkHandleDispatcherEvent(privconn, prlEvent);
+            break;
         default:
             VIR_DEBUG("Skipping event of issuer type %d", prlIssuerType);
     }
diff --git a/src/vz/vz_utils.h b/src/vz/vz_utils.h
index 9b46bf9..b0dc3d8 100644
--- a/src/vz/vz_utils.h
+++ b/src/vz/vz_utils.h
@@ -32,6 +32,7 @@
 # include "conf/network_conf.h"
 # include "virthread.h"
 # include "virjson.h"
+# include "datatypes.h"
 
 # define vzParseError()                                                 \
     virReportErrorHelper(VIR_FROM_TEST, VIR_ERR_OPERATION_FAILED, __FILE__,    \
@@ -69,6 +70,8 @@ struct _vzConn {
     virObjectEventStatePtr domainEventState;
     virStorageDriverStatePtr storageState;
     const char *drivername;
+    /* Immutable pointer, self-locking APIs */
+    virConnectCloseCallbackPtr closeCallback;
 };
 
 typedef struct _vzConn vzConn;
-- 
1.7.1




More information about the libvir-list mailing list