Reuse virConnectCloseCallback to implement connection close event functions. Thus we automatically meet multi-thread requirements on unregistering/notification. Signed-off-by: Nikolay Shirokovskiy <nshirokovskiy@xxxxxxxxxxxxx> --- 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list