close callback: move it to driver

Signed-off-by: Nikolay Shirokovskiy <nshirokovskiy@virtuozzo.com>
This commit is contained in:
Nikolay Shirokovskiy 2016-03-01 14:17:38 +00:00 committed by Daniel P. Berrange
parent bb5827950e
commit 88f09b75eb
5 changed files with 90 additions and 41 deletions

View File

@ -118,22 +118,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);
}
/**
@ -154,14 +142,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);
}
}
@ -189,6 +169,15 @@ virConnectCloseCallbackDataDispose(void *obj)
virConnectCloseCallbackDataReset(obj);
}
virConnectCloseCallbackDataPtr
virNewConnectCloseCallbackData(void)
{
if (virDataTypesInitialize() < 0)
return NULL;
return virObjectLockableNew(virConnectCloseCallbackDataClass);
}
void virConnectCloseCallbackDataRegister(virConnectCloseCallbackDataPtr close,
virConnectPtr conn,
virConnectCloseFunc cb,

View File

@ -421,9 +421,6 @@ struct _virConnect {
virError err; /* the last error */
virErrorFunc handler; /* associated handler */
void *userData; /* the user data */
/* Per-connection close callback */
virConnectCloseCallbackDataPtr closeCallback;
};
/**
@ -640,6 +637,7 @@ virAdmConnectPtr virAdmConnectNew(void);
virAdmServerPtr virAdmGetServer(virAdmConnectPtr conn,
const char *name);
virConnectCloseCallbackDataPtr virNewConnectCloseCallbackData(void);
void virConnectCloseCallbackDataRegister(virConnectCloseCallbackDataPtr close,
virConnectPtr conn,
virConnectCloseFunc cb,

View File

@ -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;
};

View File

@ -1217,14 +1217,9 @@ virConnectRegisterCloseCallback(virConnectPtr conn,
virCheckConnectReturn(conn, -1);
virCheckNonNullArgGoto(cb, error);
if (virConnectCloseCallbackDataGetCallback(conn->closeCallback) != NULL) {
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
_("A close callback is already registered"));
if (conn->driver->connectRegisterCloseCallback &&
conn->driver->connectRegisterCloseCallback(conn, cb, opaque, freecb) < 0)
goto error;
}
virConnectCloseCallbackDataRegister(conn->closeCallback, conn, cb,
opaque, freecb);
return 0;
@ -1257,13 +1252,9 @@ virConnectUnregisterCloseCallback(virConnectPtr conn,
virCheckConnectReturn(conn, -1);
virCheckNonNullArgGoto(cb, error);
if (virConnectCloseCallbackDataGetCallback(conn->closeCallback) != cb) {
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
_("A different callback was requested"));
if (conn->driver->connectUnregisterCloseCallback &&
conn->driver->connectUnregisterCloseCallback(conn, cb) < 0)
goto error;
}
virConnectCloseCallbackDataUnregister(conn->closeCallback, cb);
return 0;

View File

@ -96,6 +96,7 @@ struct private_data {
bool serverEventFilter; /* Does server support modern event filtering */
virObjectEventStatePtr eventState;
virConnectCloseCallbackDataPtr closeCallback;
};
enum {
@ -963,11 +964,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,
@ -1097,6 +1100,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;
@ -1229,11 +1234,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);
@ -7887,6 +7894,56 @@ 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);
if (virConnectCloseCallbackDataGetCallback(priv->closeCallback) != NULL) {
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
_("A close callback is already registered"));
goto cleanup;
}
virConnectCloseCallbackDataRegister(priv->closeCallback, conn, cb,
opaque, freecb);
ret = 0;
cleanup:
remoteDriverUnlock(priv);
return ret;
}
static int
remoteConnectUnregisterCloseCallback(virConnectPtr conn,
virConnectCloseFunc cb)
{
struct private_data *priv = conn->privateData;
int ret = -1;
remoteDriverLock(priv);
if (virConnectCloseCallbackDataGetCallback(priv->closeCallback) != cb) {
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
_("A different callback was requested"));
goto cleanup;
}
virConnectCloseCallbackDataUnregister(priv->closeCallback, cb);
ret = 0;
cleanup:
remoteDriverUnlock(priv);
return ret;
}
static int
remoteDomainRename(virDomainPtr dom, const char *new_name, unsigned int flags)
@ -8279,6 +8336,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 = {