[libvirt] [PATCH v5 10/10] vz: implement connection close notification

Nikolay Shirokovskiy nshirokovskiy at virtuozzo.com
Wed Feb 17 12:15:03 UTC 2016


Signed-off-by: Nikolay Shirokovskiy <nshirokovskiy at virtuozzo.com>
---
 src/vz/vz_driver.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/vz/vz_sdk.c    |  4 ++++
 src/vz/vz_utils.h  |  3 +++
 3 files changed, 66 insertions(+)

diff --git a/src/vz/vz_driver.c b/src/vz/vz_driver.c
index 925ff32..00e0f67 100644
--- a/src/vz/vz_driver.c
+++ b/src/vz/vz_driver.c
@@ -254,6 +254,9 @@ vzOpenDefault(virConnectPtr conn)
     if (prlsdkSubscribeToPCSEvents(privconn))
         goto error;
 
+    if (!(privconn->closeCallback = virNewConnectCloseCallbackData()))
+        goto error;
+
     conn->privateData = privconn;
 
     if (prlsdkLoadDomains(privconn))
@@ -262,6 +265,8 @@ vzOpenDefault(virConnectPtr conn)
     return VIR_DRV_OPEN_SUCCESS;
 
  error:
+    virObjectUnref(privconn->closeCallback);
+    privconn->closeCallback = NULL;
     virObjectUnref(privconn->domains);
     virObjectUnref(privconn->caps);
     virObjectEventStateFree(privconn->domainEventState);
@@ -329,6 +334,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;
@@ -1461,6 +1468,56 @@ vzNodeGetFreeMemory(virConnectPtr conn ATTRIBUTE_UNUSED)
     return freeMem;
 }
 
+static int
+vzConnectRegisterCloseCallback(virConnectPtr conn,
+                               virConnectCloseFunc cb,
+                               void *opaque,
+                               virFreeCallback freecb)
+{
+    vzConnPtr privconn = conn->privateData;
+    int ret = -1;
+
+    vzDriverLock(privconn);
+
+    if (virConnectCloseCallbackDataGetCallback(privconn->closeCallback) != NULL) {
+        virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+                       _("A close callback is already registered"));
+        goto cleanup;
+    }
+
+    virConnectCloseCallbackDataRegister(privconn->closeCallback, conn, cb,
+                                        opaque, freecb);
+    ret = 0;
+
+ cleanup:
+    vzDriverUnlock(privconn);
+
+    return ret;
+}
+
+static int
+vzConnectUnregisterCloseCallback(virConnectPtr conn, virConnectCloseFunc cb)
+{
+    vzConnPtr privconn = conn->privateData;
+    int ret = -1;
+
+    vzDriverLock(privconn);
+
+    if (virConnectCloseCallbackDataGetCallback(privconn->closeCallback) != cb) {
+        virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+                       _("A different callback was requested"));
+        goto cleanup;
+    }
+
+    virConnectCloseCallbackDataUnregister(privconn->closeCallback, cb);
+    ret = 0;
+
+ cleanup:
+    vzDriverUnlock(privconn);
+
+    return ret;
+}
+
 static virHypervisorDriver vzDriver = {
     .name = "vz",
     .connectOpen = vzConnectOpen,            /* 0.10.0 */
@@ -1523,6 +1580,8 @@ static virHypervisorDriver vzDriver = {
     .domainBlockStatsFlags = vzDomainBlockStatsFlags, /* 1.2.17 */
     .domainInterfaceStats = vzDomainInterfaceStats, /* 1.2.17 */
     .domainMemoryStats = vzDomainMemoryStats, /* 1.2.17 */
+    .connectRegisterCloseCallback = vzConnectRegisterCloseCallback, /* 1.3.2 */
+    .connectUnregisterCloseCallback = vzConnectUnregisterCloseCallback, /* 1.3.2 */
 };
 
 static virConnectDriver vzConnectDriver = {
diff --git a/src/vz/vz_sdk.c b/src/vz/vz_sdk.c
index 30ea545..6798aaa 100644
--- a/src/vz/vz_sdk.c
+++ b/src/vz/vz_sdk.c
@@ -1751,6 +1751,10 @@ prlsdkEventsHandler(PRL_HANDLE prlEvent, PRL_VOID_PTR opaque)
         /* above function takes own of event */
         prlEvent = PRL_INVALID_HANDLE;
         break;
+    case PET_DSP_EVT_DISP_CONNECTION_CLOSED:
+        virConnectCloseCallbackDataCall(privconn->closeCallback,
+                                        VIR_CONNECT_CLOSE_REASON_EOF);
+        break;
     default:
         VIR_DEBUG("Skipping event of type %d", prlEventType);
     }
diff --git a/src/vz/vz_utils.h b/src/vz/vz_utils.h
index b7a4c81..a2468b4 100644
--- a/src/vz/vz_utils.h
+++ b/src/vz/vz_utils.h
@@ -30,6 +30,7 @@
 # include "conf/virdomainobjlist.h"
 # include "conf/domain_event.h"
 # include "virthread.h"
+# include "datatypes.h"
 
 # define vzParseError()                                                 \
     virReportErrorHelper(VIR_FROM_TEST, VIR_ERR_OPERATION_FAILED, __FILE__,    \
@@ -59,6 +60,8 @@ struct _vzConn {
     virDomainXMLOptionPtr xmlopt;
     virObjectEventStatePtr domainEventState;
     const char *drivername;
+    /* Immutable pointer, self-locking APIs */
+    virConnectCloseCallbackDataPtr closeCallback;
 };
 
 typedef struct _vzConn vzConn;
-- 
1.8.3.1




More information about the libvir-list mailing list