Signed-off-by: Nikolay Shirokovskiy <nshirokovskiy(a)virtuozzo.com>
---
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