Reuse virConnectCloseCallback to implement connection close event functions.
Thus we automatically meet multi-thread requirements on unregistering/notification.
Signed-off-by: Nikolay Shirokovskiy <nshirokovskiy(a)virtuozzo.com>
---
daemon/remote.c | 2 +-
src/remote/remote_driver.c | 3 ++-
src/vz/vz_driver.c | 26 ++++++++++++++++++++++++++
src/vz/vz_sdk.c | 32 ++++++++++++++++++++++++++++++--
src/vz/vz_utils.h | 3 +++
5 files changed, 62 insertions(+), 4 deletions(-)
diff --git a/daemon/remote.c b/daemon/remote.c
index e0cc008..ca4b63d 100644
--- a/daemon/remote.c
+++ b/daemon/remote.c
@@ -1198,7 +1198,7 @@ void remoteRelayConnectionClosedEvent(virConnectPtr conn
ATTRIBUTE_UNUSED, int r
remote_connect_event_connection_closed_msg msg = { reason };
remoteDispatchObjectEventSend(client, remoteProgram,
- REMOTE_PROC_CONNECT_CLOSE,
+ REMOTE_PROC_CONNECT_EVENT_CONNECTION_CLOSED,
(xdrproc_t)xdr_remote_connect_event_connection_closed_msg,
&msg);
}
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index e6236be..90f813a 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -522,9 +522,10 @@ remoteConnectNotifyEventConnectionClosed(virNetClientProgramPtr prog
ATTRIBUTE_U
void *evdata, void *opaque)
{
virConnectPtr conn = opaque;
+ struct private_data *priv = conn->privateData;
remote_connect_event_connection_closed_msg *msg = evdata;
- virConnectCloseCallbackCall(conn->privateData, msg->reason);
+ virConnectCloseCallbackCall(priv->closeCallback, msg->reason);
}
static void
diff --git a/src/vz/vz_driver.c b/src/vz/vz_driver.c
index cef3c77..26caf19 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;
@@ -1321,6 +1328,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",
@@ -1373,6 +1397,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 98f7a57..fef064c 100644
--- a/src/vz/vz_sdk.c
+++ b/src/vz/vz_sdk.c
@@ -1736,8 +1736,7 @@ prlsdkHandleVmEvent(vzConnPtr privconn, PRL_HANDLE prlEvent)
prlEvent = PRL_INVALID_HANDLE;
break;
default:
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("Can't handle event of type %d"), prlEventType);
+ VIR_DEBUG("Skipping vm event of type %d", prlEventType);
}
cleanup:
@@ -1745,6 +1744,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 +1797,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