Signed-off-by: Nikolay Shirokovskiy <nshirokovskiy@xxxxxxxxxxxxx> --- src/datatypes.c | 31 ++++++++++-------------------- src/datatypes.h | 1 + src/driver-hypervisor.h | 12 ++++++++++++ src/libvirt-host.c | 7 ++++--- src/remote/remote_driver.c | 47 ++++++++++++++++++++++++++++++++++++++++++---- 5 files changed, 70 insertions(+), 28 deletions(-) diff --git a/src/datatypes.c b/src/datatypes.c index 29f94e8..f7e9f52 100644 --- a/src/datatypes.c +++ b/src/datatypes.c @@ -114,22 +114,10 @@ VIR_ONCE_GLOBAL_INIT(virDataTypes) virConnectPtr virGetConnect(void) { - virConnectPtr ret; - if (virDataTypesInitialize() < 0) return NULL; - if (!(ret = virObjectLockableNew(virConnectClass))) - return NULL; - - if (!(ret->closeCallback = virObjectLockableNew(virConnectCloseCallbackDataClass))) - goto error; - - return ret; - - error: - virObjectUnref(ret); - return NULL; + return virObjectLockableNew(virConnectClass); } /** @@ -150,14 +138,6 @@ virConnectDispose(void *obj) virResetError(&conn->err); virURIFree(conn->uri); - - if (conn->closeCallback) { - virObjectLock(conn->closeCallback); - conn->closeCallback->callback = NULL; - virObjectUnlock(conn->closeCallback); - - virObjectUnref(conn->closeCallback); - } } @@ -186,6 +166,15 @@ virConnectCloseCallbackDataDispose(void *obj) virConnectCloseCallbackDataReset(obj); } +virConnectCloseCallbackDataPtr +virNewConnectCloseCallbackData(void) +{ + if (virDataTypesInitialize() < 0) + return NULL; + + return virObjectLockableNew(virConnectCloseCallbackDataClass); +} + int virConnectCloseCallbackDataRegister(virConnectCloseCallbackDataPtr close, virConnectPtr conn, virConnectCloseFunc cb, diff --git a/src/datatypes.h b/src/datatypes.h index 096f80f..0e99d6a 100644 --- a/src/datatypes.h +++ b/src/datatypes.h @@ -601,6 +601,7 @@ virDomainSnapshotPtr virGetDomainSnapshot(virDomainPtr domain, virAdmConnectPtr virAdmConnectNew(void); +virConnectCloseCallbackDataPtr virNewConnectCloseCallbackData(void); int virConnectCloseCallbackDataRegister(virConnectCloseCallbackDataPtr close, virConnectPtr conn, virConnectCloseFunc cb, diff --git a/src/driver-hypervisor.h b/src/driver-hypervisor.h index ae2ec4d..2cbd01b 100644 --- a/src/driver-hypervisor.h +++ b/src/driver-hypervisor.h @@ -1212,6 +1212,16 @@ typedef int const char *password, unsigned int flags); +typedef int +(*virDrvConnectRegisterCloseCallback)(virConnectPtr conn, + virConnectCloseFunc cb, + void *opaque, + virFreeCallback freecb); + +typedef int +(*virDrvConnectUnregisterCloseCallback)(virConnectPtr conn, + virConnectCloseFunc cb); + typedef struct _virHypervisorDriver virHypervisorDriver; typedef virHypervisorDriver *virHypervisorDriverPtr; @@ -1443,6 +1453,8 @@ struct _virHypervisorDriver { virDrvDomainGetFSInfo domainGetFSInfo; virDrvDomainInterfaceAddresses domainInterfaceAddresses; virDrvDomainSetUserPassword domainSetUserPassword; + virDrvConnectRegisterCloseCallback connectRegisterCloseCallback; + virDrvConnectUnregisterCloseCallback connectUnregisterCloseCallback; }; diff --git a/src/libvirt-host.c b/src/libvirt-host.c index 0bab5f2..24277b7 100644 --- a/src/libvirt-host.c +++ b/src/libvirt-host.c @@ -1217,8 +1217,8 @@ virConnectRegisterCloseCallback(virConnectPtr conn, virCheckConnectReturn(conn, -1); virCheckNonNullArgGoto(cb, error); - if (virConnectCloseCallbackDataRegister(conn->closeCallback, conn, cb, - opaque, freecb) < 0) + if (conn->driver->connectRegisterCloseCallback && + conn->driver->connectRegisterCloseCallback(conn, cb, opaque, freecb) < 0) goto error; return 0; @@ -1252,7 +1252,8 @@ virConnectUnregisterCloseCallback(virConnectPtr conn, virCheckConnectReturn(conn, -1); virCheckNonNullArgGoto(cb, error); - if (virConnectCloseCallbackDataUnregister(conn->closeCallback, cb) < 0) + if (conn->driver->connectUnregisterCloseCallback && + conn->driver->connectUnregisterCloseCallback(conn, cb) < 0) goto error; return 0; diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 7fc257a..f64ce4d 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -101,6 +101,7 @@ struct private_data { bool serverEventFilter; /* Does server support modern event filtering */ virObjectEventStatePtr eventState; + virConnectCloseCallbackDataPtr closeCallback; }; enum { @@ -968,11 +969,13 @@ doRemoteOpen(virConnectPtr conn, goto failed; } - virObjectRef(conn->closeCallback); - + if (!(priv->closeCallback = virNewConnectCloseCallbackData())) + goto failed; + // ref on behalf of netclient + virObjectRef(priv->closeCallback); virNetClientSetCloseCallback(priv->client, remoteClientCloseFunc, - conn->closeCallback, virObjectFreeCallback); + priv->closeCallback, virObjectFreeCallback); if (!(priv->remoteProgram = virNetClientProgramNew(REMOTE_PROGRAM, REMOTE_PROTOCOL_VERSION, @@ -1102,6 +1105,8 @@ doRemoteOpen(virConnectPtr conn, virNetClientClose(priv->client); virObjectUnref(priv->client); priv->client = NULL; + virObjectUnref(priv->closeCallback); + priv->closeCallback = NULL; #ifdef WITH_GNUTLS virObjectUnref(priv->tls); priv->tls = NULL; @@ -1234,11 +1239,13 @@ doRemoteClose(virConnectPtr conn, struct private_data *priv) virNetClientSetCloseCallback(priv->client, NULL, - conn->closeCallback, virObjectFreeCallback); + priv->closeCallback, virObjectFreeCallback); virNetClientClose(priv->client); virObjectUnref(priv->client); priv->client = NULL; + virObjectUnref(priv->closeCallback); + priv->closeCallback = NULL; virObjectUnref(priv->remoteProgram); virObjectUnref(priv->lxcProgram); virObjectUnref(priv->qemuProgram); @@ -8057,6 +8064,36 @@ remoteDomainInterfaceAddresses(virDomainPtr dom, return rv; } +static int +remoteConnectRegisterCloseCallback(virConnectPtr conn, + virConnectCloseFunc cb, + void *opaque, + virFreeCallback freecb) +{ + struct private_data *priv = conn->privateData; + int ret = -1; + + remoteDriverLock(priv); + ret = virConnectCloseCallbackDataRegister(priv->closeCallback, conn, cb, + opaque, freecb); + remoteDriverUnlock(priv); + + return ret; +} + +static int +remoteConnectUnregisterCloseCallback(virConnectPtr conn, + virConnectCloseFunc cb) +{ + struct private_data *priv = conn->privateData; + int ret = -1; + + remoteDriverLock(priv); + ret = virConnectCloseCallbackDataUnregister(priv->closeCallback, cb); + remoteDriverUnlock(priv); + + return ret; +} static int remoteDomainRename(virDomainPtr dom, const char *new_name, unsigned int flags) @@ -8449,6 +8486,8 @@ static virHypervisorDriver hypervisor_driver = { .domainInterfaceAddresses = remoteDomainInterfaceAddresses, /* 1.2.14 */ .domainSetUserPassword = remoteDomainSetUserPassword, /* 1.2.16 */ .domainRename = remoteDomainRename, /* 1.2.19 */ + .connectRegisterCloseCallback = remoteConnectRegisterCloseCallback, /* 1.3.2 */ + .connectUnregisterCloseCallback = remoteConnectUnregisterCloseCallback, /* 1.3.2 */ }; static virNetworkDriver network_driver = { -- 1.8.3.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list