daemon: add connection close rpc

Signed-off-by: Nikolay Shirokovskiy <nshirokovskiy@virtuozzo.com>
This commit is contained in:
Nikolay Shirokovskiy 2016-02-17 15:15:02 +03:00 committed by Daniel P. Berrange
parent ec4ef72c13
commit f484310add
6 changed files with 160 additions and 1 deletions

View File

@ -60,6 +60,7 @@ struct daemonClientPrivate {
size_t nnetworkEventCallbacks; size_t nnetworkEventCallbacks;
daemonClientEventCallbackPtr *qemuEventCallbacks; daemonClientEventCallbackPtr *qemuEventCallbacks;
size_t nqemuEventCallbacks; size_t nqemuEventCallbacks;
bool closeRegistered;
# if WITH_SASL # if WITH_SASL
virNetSASLSessionPtr sasl; virNetSASLSessionPtr sasl;

View File

@ -1208,6 +1208,20 @@ remoteRelayDomainQemuMonitorEvent(virConnectPtr conn,
VIR_FREE(details_p); VIR_FREE(details_p);
} }
static
void remoteRelayConnectionClosedEvent(virConnectPtr conn ATTRIBUTE_UNUSED, int reason, void *opaque)
{
virNetServerClientPtr client = opaque;
VIR_DEBUG("Relaying connection closed event, reason %d", reason);
remote_connect_event_connection_closed_msg msg = { reason };
remoteDispatchObjectEventSend(client, remoteProgram,
REMOTE_PROC_CONNECT_EVENT_CONNECTION_CLOSED,
(xdrproc_t)xdr_remote_connect_event_connection_closed_msg,
&msg);
}
/* /*
* You must hold lock for at least the client * You must hold lock for at least the client
* We don't free stuff here, merely disconnect the client's * We don't free stuff here, merely disconnect the client's
@ -1270,6 +1284,12 @@ void remoteClientFreeFunc(void *data)
} }
VIR_FREE(priv->qemuEventCallbacks); VIR_FREE(priv->qemuEventCallbacks);
if (priv->closeRegistered) {
if (virConnectUnregisterCloseCallback(priv->conn,
remoteRelayConnectionClosedEvent) < 0)
VIR_WARN("unexpected close callback event deregister failure");
}
virConnectClose(priv->conn); virConnectClose(priv->conn);
virIdentitySetCurrent(NULL); virIdentitySetCurrent(NULL);
@ -3345,6 +3365,70 @@ remoteDispatchNodeDeviceGetParent(virNetServerPtr server ATTRIBUTE_UNUSED,
return rv; return rv;
} }
static int
remoteDispatchConnectCloseCallbackRegister(virNetServerPtr server ATTRIBUTE_UNUSED,
virNetServerClientPtr client,
virNetMessagePtr msg ATTRIBUTE_UNUSED,
virNetMessageErrorPtr rerr)
{
int rv = -1;
struct daemonClientPrivate *priv =
virNetServerClientGetPrivateData(client);
virMutexLock(&priv->lock);
if (!priv->conn) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("connection not open"));
goto cleanup;
}
// on behalf of close callback
virObjectRef(client);
if (virConnectRegisterCloseCallback(priv->conn,
remoteRelayConnectionClosedEvent,
client, virObjectFreeCallback) < 0)
goto cleanup;
priv->closeRegistered = true;
rv = 0;
cleanup:
virMutexUnlock(&priv->lock);
if (rv < 0)
virNetMessageSaveError(rerr);
return rv;
}
static int
remoteDispatchConnectCloseCallbackUnregister(virNetServerPtr server ATTRIBUTE_UNUSED,
virNetServerClientPtr client,
virNetMessagePtr msg ATTRIBUTE_UNUSED,
virNetMessageErrorPtr rerr)
{
int rv = -1;
struct daemonClientPrivate *priv =
virNetServerClientGetPrivateData(client);
virMutexLock(&priv->lock);
if (!priv->conn) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("connection not open"));
goto cleanup;
}
if (virConnectUnregisterCloseCallback(priv->conn,
remoteRelayConnectionClosedEvent) < 0)
goto cleanup;
priv->closeRegistered = false;
rv = 0;
cleanup:
virMutexUnlock(&priv->lock);
if (rv < 0)
virNetMessageSaveError(rerr);
return rv;
}
/*************************** /***************************
* Register / deregister events * Register / deregister events
@ -4145,6 +4229,7 @@ static int remoteDispatchConnectSupportsFeature(virNetServerPtr server ATTRIBUTE
switch (args->feature) { switch (args->feature) {
case VIR_DRV_FEATURE_FD_PASSING: case VIR_DRV_FEATURE_FD_PASSING:
case VIR_DRV_FEATURE_REMOTE_EVENT_CALLBACK: case VIR_DRV_FEATURE_REMOTE_EVENT_CALLBACK:
case VIR_DRV_FEATURE_REMOTE_CLOSE_CALLBACK:
supported = 1; supported = 1;
break; break;

View File

@ -118,6 +118,11 @@ enum {
* Support for server-side event filtering via callback ids in events. * Support for server-side event filtering via callback ids in events.
*/ */
VIR_DRV_FEATURE_REMOTE_EVENT_CALLBACK = 14, VIR_DRV_FEATURE_REMOTE_EVENT_CALLBACK = 14,
/*
* Support for driver close callback rpc
*/
VIR_DRV_FEATURE_REMOTE_CLOSE_CALLBACK = 15,
}; };

View File

@ -94,6 +94,7 @@ struct private_data {
char *hostname; /* Original hostname */ char *hostname; /* Original hostname */
bool serverKeepAlive; /* Does server support keepalive protocol? */ bool serverKeepAlive; /* Does server support keepalive protocol? */
bool serverEventFilter; /* Does server support modern event filtering */ bool serverEventFilter; /* Does server support modern event filtering */
bool serverCloseCallback; /* Does server support driver close callback */
virObjectEventStatePtr eventState; virObjectEventStatePtr eventState;
virConnectCloseCallbackDataPtr closeCallback; virConnectCloseCallbackDataPtr closeCallback;
@ -347,6 +348,11 @@ remoteNetworkBuildEventLifecycle(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
virNetClientPtr client ATTRIBUTE_UNUSED, virNetClientPtr client ATTRIBUTE_UNUSED,
void *evdata, void *opaque); void *evdata, void *opaque);
static void
remoteConnectNotifyEventConnectionClosed(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
virNetClientPtr client ATTRIBUTE_UNUSED,
void *evdata, void *opaque);
static virNetClientProgramEvent remoteEvents[] = { static virNetClientProgramEvent remoteEvents[] = {
{ REMOTE_PROC_DOMAIN_EVENT_LIFECYCLE, { REMOTE_PROC_DOMAIN_EVENT_LIFECYCLE,
remoteDomainBuildEventLifecycle, remoteDomainBuildEventLifecycle,
@ -509,8 +515,23 @@ static virNetClientProgramEvent remoteEvents[] = {
remoteDomainBuildEventCallbackMigrationIteration, remoteDomainBuildEventCallbackMigrationIteration,
sizeof(remote_domain_event_callback_migration_iteration_msg), sizeof(remote_domain_event_callback_migration_iteration_msg),
(xdrproc_t)xdr_remote_domain_event_callback_migration_iteration_msg }, (xdrproc_t)xdr_remote_domain_event_callback_migration_iteration_msg },
{ REMOTE_PROC_CONNECT_EVENT_CONNECTION_CLOSED,
remoteConnectNotifyEventConnectionClosed,
sizeof(remote_connect_event_connection_closed_msg),
(xdrproc_t)xdr_remote_connect_event_connection_closed_msg },
}; };
static void
remoteConnectNotifyEventConnectionClosed(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
virNetClientPtr client ATTRIBUTE_UNUSED,
void *evdata, void *opaque)
{
virConnectPtr conn = opaque;
struct private_data *priv = conn->privateData;
remote_connect_event_connection_closed_msg *msg = evdata;
virConnectCloseCallbackDataCall(priv->closeCallback, msg->reason);
}
static void static void
remoteDomainBuildQemuMonitorEvent(virNetClientProgramPtr prog ATTRIBUTE_UNUSED, remoteDomainBuildQemuMonitorEvent(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
@ -1067,6 +1088,13 @@ doRemoteOpen(virConnectPtr conn,
"supported by the server"); "supported by the server");
} }
priv->serverCloseCallback = remoteConnectSupportsFeatureUnlocked(conn,
priv, VIR_DRV_FEATURE_REMOTE_CLOSE_CALLBACK);
if (!priv->serverCloseCallback) {
VIR_INFO("Close callback registering isn't supported "
"by the remote side.");
}
/* Successful. */ /* Successful. */
retcode = VIR_DRV_OPEN_SUCCESS; retcode = VIR_DRV_OPEN_SUCCESS;
@ -7908,6 +7936,12 @@ remoteConnectRegisterCloseCallback(virConnectPtr conn,
goto cleanup; goto cleanup;
} }
if (priv->serverCloseCallback &&
call(conn, priv, 0, REMOTE_PROC_CONNECT_CLOSE_CALLBACK_REGISTER,
(xdrproc_t) xdr_void, (char *) NULL,
(xdrproc_t) xdr_void, (char *) NULL) == -1)
goto cleanup;
virConnectCloseCallbackDataRegister(priv->closeCallback, conn, cb, virConnectCloseCallbackDataRegister(priv->closeCallback, conn, cb,
opaque, freecb); opaque, freecb);
ret = 0; ret = 0;
@ -7933,6 +7967,12 @@ remoteConnectUnregisterCloseCallback(virConnectPtr conn,
goto cleanup; goto cleanup;
} }
if (priv->serverCloseCallback &&
call(conn, priv, 0, REMOTE_PROC_CONNECT_CLOSE_CALLBACK_UNREGISTER,
(xdrproc_t) xdr_void, (char *) NULL,
(xdrproc_t) xdr_void, (char *) NULL) == -1)
goto cleanup;
virConnectCloseCallbackDataUnregister(priv->closeCallback, cb); virConnectCloseCallbackDataUnregister(priv->closeCallback, cb);
ret = 0; ret = 0;

View File

@ -3045,6 +3045,10 @@ struct remote_domain_event_callback_device_added_msg {
remote_nonnull_string devAlias; remote_nonnull_string devAlias;
}; };
struct remote_connect_event_connection_closed_msg {
int reason;
};
struct remote_connect_get_cpu_model_names_args { struct remote_connect_get_cpu_model_names_args {
remote_nonnull_string arch; remote_nonnull_string arch;
int need_results; int need_results;
@ -5706,5 +5710,23 @@ enum remote_procedure {
* @generate: both * @generate: both
* @acl: none * @acl: none
*/ */
REMOTE_PROC_DOMAIN_EVENT_CALLBACK_MIGRATION_ITERATION = 359 REMOTE_PROC_DOMAIN_EVENT_CALLBACK_MIGRATION_ITERATION = 359,
/**
* @generate: none
* @acl: none
*/
REMOTE_PROC_CONNECT_CLOSE_CALLBACK_REGISTER = 360,
/**
* @generate: none
* @acl: none
*/
REMOTE_PROC_CONNECT_CLOSE_CALLBACK_UNREGISTER = 361,
/**
* @generate: none
* @acl: none
*/
REMOTE_PROC_CONNECT_EVENT_CONNECTION_CLOSED = 362
}; };

View File

@ -2502,6 +2502,9 @@ struct remote_domain_event_callback_device_added_msg {
remote_nonnull_domain dom; remote_nonnull_domain dom;
remote_nonnull_string devAlias; remote_nonnull_string devAlias;
}; };
struct remote_connect_event_connection_closed_msg {
int reason;
};
struct remote_connect_get_cpu_model_names_args { struct remote_connect_get_cpu_model_names_args {
remote_nonnull_string arch; remote_nonnull_string arch;
int need_results; int need_results;
@ -3057,4 +3060,7 @@ enum remote_procedure {
REMOTE_PROC_DOMAIN_SET_USER_PASSWORD = 357, REMOTE_PROC_DOMAIN_SET_USER_PASSWORD = 357,
REMOTE_PROC_DOMAIN_RENAME = 358, REMOTE_PROC_DOMAIN_RENAME = 358,
REMOTE_PROC_DOMAIN_EVENT_CALLBACK_MIGRATION_ITERATION = 359, REMOTE_PROC_DOMAIN_EVENT_CALLBACK_MIGRATION_ITERATION = 359,
REMOTE_PROC_CONNECT_CLOSE_CALLBACK_REGISTER = 360,
REMOTE_PROC_CONNECT_CLOSE_CALLBACK_UNREGISTER = 361,
REMOTE_PROC_CONNECT_EVENT_CONNECTION_CLOSED = 362,
}; };