[libvirt] [PATCH v2 7/9] admin: Add support for connection close callbacks
Martin Kletzander
mkletzan at redhat.com
Tue Nov 3 20:05:45 UTC 2015
On Fri, Oct 16, 2015 at 08:12:24PM +0200, Erik Skultety wrote:
>As we need a client disconnect handler, we also need a mechanism to register
>such handlers for a client. This patch introduced both the close callbacks and
>also the client vshAdmCatchDisconnect handler to be registered with it. By
>registering the handler we still need to make sure the client can react to
>daemon's events like disconnect or keepalive, so asynchronous I/O event polling
>is necessary to be enabled too.
>---
> include/libvirt/libvirt-admin.h | 19 +++++++
> src/admin/admin_remote.c | 36 +++++++++++++
> src/datatypes.c | 20 +++++++
> src/datatypes.h | 14 ++++-
> src/libvirt-admin.c | 112 ++++++++++++++++++++++++++++++++++++++++
> src/libvirt_admin_public.syms | 2 +
> tools/virt-admin.c | 50 ++++++++++++++++++
> 7 files changed, 252 insertions(+), 1 deletion(-)
>
>diff --git a/include/libvirt/libvirt-admin.h b/include/libvirt/libvirt-admin.h
>index aae10b4..1688201 100644
>--- a/include/libvirt/libvirt-admin.h
>+++ b/include/libvirt/libvirt-admin.h
>@@ -56,6 +56,25 @@ int virAdmConnectIsAlive(virAdmConnectPtr conn);
>
> char * virAdmConnectGetURI(virAdmConnectPtr conn);
>
>+/**
>+ * virAdmConnectCloseFunc:
>+ * @conn: virAdmConnect connection
>+ * @reason: reason why the connection was closed (see virConnectCloseReason)
>+ * @opaque: opaque client data
>+ *
>+ * A callback to be registered, in case a connection was closed.
>+ */
>+typedef void (*virAdmConnectCloseFunc)(virAdmConnectPtr conn,
>+ int reason,
>+ void *opaque);
>+
>+int virAdmConnectRegisterCloseCallback(virAdmConnectPtr conn,
>+ virAdmConnectCloseFunc cb,
>+ void *opaque,
>+ virFreeCallback freecb);
>+int virAdmConnectUnregisterCloseCallback(virAdmConnectPtr conn,
>+ virAdmConnectCloseFunc cb);
>+
> # ifdef __cplusplus
> }
> # endif
>diff --git a/src/admin/admin_remote.c b/src/admin/admin_remote.c
>index 2c02ba6..741b9a1 100644
>--- a/src/admin/admin_remote.c
>+++ b/src/admin/admin_remote.c
>@@ -101,6 +101,28 @@ call(virAdmConnectPtr conn,
>
> #include "admin_client.h"
>
>+static void
>+remoteAdminClientCloseFunc(virNetClientPtr client ATTRIBUTE_UNUSED,
>+ int reason,
>+ void *opaque)
>+{
>+ virAdmConnectCloseCallbackDataPtr cbdata = opaque;
>+
>+ virObjectLock(cbdata);
>+
>+ if (cbdata->callback) {
>+ VIR_DEBUG("Triggering connection close callback %p reason=%d, opaque=%p",
>+ cbdata->callback, reason, cbdata->opaque);
>+ cbdata->callback(cbdata->conn, reason, cbdata->opaque);
>+
>+ if (cbdata->freeCallback)
>+ cbdata->freeCallback(cbdata->opaque);
>+ cbdata->callback = NULL;
>+ cbdata->freeCallback = NULL;
>+ }
>+ virObjectUnlock(cbdata);
>+}
>+
> static int
> remoteAdminConnectOpen(virAdmConnectPtr conn, unsigned int flags)
> {
>@@ -112,6 +134,17 @@ remoteAdminConnectOpen(virAdmConnectPtr conn, unsigned int flags)
>
> args.flags = flags;
>
>+ if (virNetClientRegisterAsyncIO(priv->client) < 0) {
>+ VIR_DEBUG("Failed to add event watch, disabling events and support for"
>+ " keepalive messages");
>+ virResetLastError();
>+ }
>+
>+ virObjectRef(conn->closeCallback);
>+ virNetClientSetCloseCallback(priv->client, remoteAdminClientCloseFunc,
>+ conn->closeCallback,
>+ virObjectFreeCallback);
>+
> if (call(conn, 0, ADMIN_PROC_CONNECT_OPEN,
> (xdrproc_t)xdr_admin_connect_open_args, (char *)&args,
> (xdrproc_t)xdr_void, (char *)NULL) == -1) {
>@@ -139,6 +172,9 @@ remoteAdminConnectClose(virAdmConnectPtr conn)
> goto done;
> }
>
>+ virNetClientSetCloseCallback(priv->client, NULL, conn->closeCallback,
>+ virObjectFreeCallback);
Again, yes, we have this code in place already, in the remote driver,
and I understand it actually means RemoveCloseCallback, but why aren't
we passing NULL as all three parameters after the client?
>+
> rv = 0;
>
> done:
>diff --git a/src/datatypes.c b/src/datatypes.c
>index aeac301..603b168 100644
>--- a/src/datatypes.c
>+++ b/src/datatypes.c
>@@ -60,8 +60,10 @@ static void virStorageVolDispose(void *obj);
> static void virStoragePoolDispose(void *obj);
>
> virClassPtr virAdmConnectClass;
>+virClassPtr virAdmConnectCloseCallbackDataClass;
>
> static void virAdmConnectDispose(void *obj);
>+static void virAdmConnectCloseCallbackDataDispose(void *obj);
>
> static int
> virDataTypesOnceInit(void)
>@@ -91,6 +93,7 @@ virDataTypesOnceInit(void)
> DECLARE_CLASS(virStoragePool);
>
> DECLARE_CLASS_LOCKABLE(virAdmConnect);
>+ DECLARE_CLASS_LOCKABLE(virAdmConnectCloseCallbackData);
>
> #undef DECLARE_CLASS_COMMON
> #undef DECLARE_CLASS_LOCKABLE
>@@ -822,6 +825,9 @@ virAdmConnectNew(void)
> if (!(ret = virObjectLockableNew(virAdmConnectClass)))
> return NULL;
>
>+ if (!(ret->closeCallback = virObjectLockableNew(virAdmConnectCloseCallbackDataClass)))
>+ return NULL;
>+
> return ret;
> }
>
>@@ -834,4 +840,18 @@ virAdmConnectDispose(void *obj)
> conn->privateDataFreeFunc(conn);
>
> virURIFree(conn->uri);
>+ virObjectUnref(conn->closeCallback);
>+}
>+
>+static void
>+virAdmConnectCloseCallbackDataDispose(void *obj)
>+{
>+ virAdmConnectCloseCallbackDataPtr cb_data = obj;
>+
>+ virObjectLock(cb_data);
>+
>+ if (cb_data->freeCallback)
>+ cb_data->freeCallback(cb_data->opaque);
>+
>+ virObjectUnlock(cb_data);
> }
>diff --git a/src/datatypes.h b/src/datatypes.h
>index 95aa49e..aa160a8 100644
>--- a/src/datatypes.h
>+++ b/src/datatypes.h
>@@ -331,9 +331,11 @@ extern virClassPtr virAdmConnectClass;
>
> typedef struct _virConnectCloseCallbackData virConnectCloseCallbackData;
> typedef virConnectCloseCallbackData *virConnectCloseCallbackDataPtr;
>+typedef struct _virAdmConnectCloseCallbackData virAdmConnectCloseCallbackData;
>+typedef virAdmConnectCloseCallbackData *virAdmConnectCloseCallbackDataPtr;
>
> /**
>- * Internal structure holding data related to connection close callbacks.
>+ * Internal structures holding data related to connection close callbacks.
> */
> struct _virConnectCloseCallbackData {
> virObjectLockable parent;
>@@ -344,6 +346,15 @@ struct _virConnectCloseCallbackData {
> virFreeCallback freeCallback;
> };
>
>+struct _virAdmConnectCloseCallbackData {
>+ virObjectLockable parent;
>+
>+ virAdmConnectPtr conn;
>+ virAdmConnectCloseFunc callback;
>+ void *opaque;
>+ virFreeCallback freeCallback;
>+};
>+
> /**
> * _virConnect:
> *
>@@ -401,6 +412,7 @@ struct _virAdmConnect {
>
> void *privateData;
> virFreeCallback privateDataFreeFunc;
I'd add one empty line here.
Otherwise looks fine to me (with the adjustments that will be needed
after previous patches are fixed, of course).
Martin
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20151103/aebf43d0/attachment-0001.sig>
More information about the libvir-list
mailing list