Finally add public method to retrieve the list of currently connected clients
to a given server.
Signed-off-by: Erik Skultety <eskultet(a)redhat.com>
---
daemon/admin.c | 15 +++++++++++++++
daemon/admin_server.c | 24 ++++++++++++++++++++++++
daemon/admin_server.h | 4 ++++
include/libvirt/libvirt-admin.h | 4 ++++
src/admin/admin_protocol.x | 21 ++++++++++++++++++++-
src/admin/admin_remote.c | 6 ++++++
src/admin_protocol-structs | 13 +++++++++++++
src/libvirt-admin.c | 41 +++++++++++++++++++++++++++++++++++++++++
src/libvirt_admin_private.syms | 2 ++
src/libvirt_admin_public.syms | 1 +
10 files changed, 130 insertions(+), 1 deletion(-)
diff --git a/daemon/admin.c b/daemon/admin.c
index 00e7dc3..fcbdee5 100644
--- a/daemon/admin.c
+++ b/daemon/admin.c
@@ -81,6 +81,12 @@ remoteAdmClientInitHook(virNetServerClientPtr client ATTRIBUTE_UNUSED,
/* Helpers */
+static virNetServerPtr
+get_nonnull_server(virNetDaemonPtr dmn, admin_nonnull_server srv)
+{
+ return virNetDaemonGetServer(dmn, srv.name);
+}
+
static void
make_nonnull_server(admin_nonnull_server *srv_dst,
virNetServerPtr srv_src)
@@ -88,6 +94,15 @@ make_nonnull_server(admin_nonnull_server *srv_dst,
ignore_value(VIR_STRDUP_QUIET(srv_dst->name, virNetServerGetName(srv_src)));
}
+static void
+make_nonnull_client(admin_nonnull_client *clt_dst,
+ virNetServerClientPtr clt_src)
+{
+ clt_dst->id = virNetServerClientGetID(clt_src);
+ clt_dst->timestamp = virNetServerClientGetTimestamp(clt_src);
+ clt_dst->transport = virNetServerClientGetTransport(clt_src);
+}
+
/* Functions */
static int
adminDispatchConnectOpen(virNetServerPtr server ATTRIBUTE_UNUSED,
diff --git a/daemon/admin_server.c b/daemon/admin_server.c
index e39a9bd..0e1e79d 100644
--- a/daemon/admin_server.c
+++ b/daemon/admin_server.c
@@ -178,3 +178,27 @@ adminServerSetThreadPoolParameters(virNetServerPtr srv,
return 0;
}
+
+int
+adminServerListClients(virNetServerPtr srv,
+ virNetServerClientPtr **clients,
+ unsigned int flags)
+{
+ int ret = -1;
+ virNetServerClientPtr *clts;
+
+ virCheckFlags(0, -1);
+
+ if ((ret = virNetServerGetClients(srv, &clts)) < 0)
+ goto cleanup;
+
+ if (clients) {
+ *clients = clts;
+ clts = NULL;
+ }
+
+ cleanup:
+ if (ret > 0)
+ virObjectListFreeCount(clts, ret);
+ return ret;
+}
diff --git a/daemon/admin_server.h b/daemon/admin_server.h
index 756e049..3e4786e 100644
--- a/daemon/admin_server.h
+++ b/daemon/admin_server.h
@@ -46,4 +46,8 @@ adminServerSetThreadPoolParameters(virNetServerPtr srv,
int nparams,
unsigned int flags);
+int adminServerListClients(virNetServerPtr srv,
+ virNetServerClientPtr **clients,
+ unsigned int flags);
+
#endif /* __LIBVIRTD_ADMIN_SERVER_H__ */
diff --git a/include/libvirt/libvirt-admin.h b/include/libvirt/libvirt-admin.h
index d38b6b7..b31b007 100644
--- a/include/libvirt/libvirt-admin.h
+++ b/include/libvirt/libvirt-admin.h
@@ -214,6 +214,10 @@ typedef enum {
# endif
} virClientTransport;
+int virAdmServerListClients(virAdmServerPtr srv,
+ virAdmClientPtr **clients,
+ unsigned int flags);
+
# ifdef __cplusplus
}
# endif
diff --git a/src/admin/admin_protocol.x b/src/admin/admin_protocol.x
index 2f302af..e77ce9e 100644
--- a/src/admin/admin_protocol.x
+++ b/src/admin/admin_protocol.x
@@ -39,6 +39,9 @@ const ADMIN_SERVER_LIST_MAX = 16384;
/* Upper limit on number of threadpool parameters */
const ADMIN_SERVER_THREADPOOL_PARAMETERS_MAX = 32;
+/* Upper limit on list of clients */
+const ADMIN_CLIENT_LIST_MAX = 16384;
+
/* A long string, which may NOT be NULL. */
typedef string admin_nonnull_string<ADMIN_STRING_MAX>;
@@ -124,6 +127,17 @@ struct admin_server_set_threadpool_parameters_args {
unsigned int flags;
};
+struct admin_server_list_clients_args {
+ admin_nonnull_server srv;
+ unsigned int need_results;
+ unsigned int flags;
+};
+
+struct admin_server_list_clients_ret { /* insert@1 */
+ admin_nonnull_client clients<ADMIN_CLIENT_LIST_MAX>;
+ unsigned int ret;
+};
+
/* Define the program number, protocol version and procedure numbers here. */
const ADMIN_PROGRAM = 0x06900690;
const ADMIN_PROTOCOL_VERSION = 1;
@@ -179,5 +193,10 @@ enum admin_procedure {
/**
* @generate: none
*/
- ADMIN_PROC_SERVER_SET_THREADPOOL_PARAMETERS = 7
+ ADMIN_PROC_SERVER_SET_THREADPOOL_PARAMETERS = 7,
+
+ /**
+ * @generate: both
+ */
+ ADMIN_PROC_SERVER_LIST_CLIENTS = 8
};
diff --git a/src/admin/admin_remote.c b/src/admin/admin_remote.c
index 2dd692b..b833ea4 100644
--- a/src/admin/admin_remote.c
+++ b/src/admin/admin_remote.c
@@ -55,6 +55,12 @@ get_nonnull_server(virAdmConnectPtr conn, admin_nonnull_server server)
return virAdmGetServer(conn, server.name);
}
+static virAdmClientPtr
+get_nonnull_client(virAdmServerPtr srv, admin_nonnull_client client)
+{
+ return virAdmGetClient(srv, client.id, client.timestamp, client.transport);
+}
+
static void
make_nonnull_server(admin_nonnull_server *srv_dst, virAdmServerPtr srv_src)
{
diff --git a/src/admin_protocol-structs b/src/admin_protocol-structs
index d4ccf9e..055ddd5 100644
--- a/src/admin_protocol-structs
+++ b/src/admin_protocol-structs
@@ -75,6 +75,18 @@ struct admin_server_set_threadpool_parameters_args {
} params;
u_int flags;
};
+struct admin_server_list_clients_args {
+ admin_nonnull_server srv;
+ u_int need_results;
+ u_int flags;
+};
+struct admin_server_list_clients_ret {
+ struct {
+ u_int clients_len;
+ admin_nonnull_client * clients_val;
+ } clients;
+ u_int ret;
+};
enum admin_procedure {
ADMIN_PROC_CONNECT_OPEN = 1,
ADMIN_PROC_CONNECT_CLOSE = 2,
@@ -83,4 +95,5 @@ enum admin_procedure {
ADMIN_PROC_CONNECT_LOOKUP_SERVER = 5,
ADMIN_PROC_SERVER_GET_THREADPOOL_PARAMETERS = 6,
ADMIN_PROC_SERVER_SET_THREADPOOL_PARAMETERS = 7,
+ ADMIN_PROC_SERVER_LIST_CLIENTS = 8,
};
diff --git a/src/libvirt-admin.c b/src/libvirt-admin.c
index b45da72..d4143e4 100644
--- a/src/libvirt-admin.c
+++ b/src/libvirt-admin.c
@@ -848,3 +848,44 @@ virAdmServerSetThreadPoolParameters(virAdmServerPtr srv,
virDispatchError(NULL);
return -1;
}
+
+/**
+ * virAdmServerListClients:
+ * @srv: a valid server object reference
+ * @clients: pointer to a list to store an array containing objects or NULL
+ * if the list is not required (number of clients only)
+ * @flags: extra flags; not used yet, so callers should always pass 0
+ *
+ * Collect list of all clients connected to daemon on server @srv.
+ *
+ * Returns the number of clients connected to daemon on server @srv -1 in case
+ * of a failure, setting @clients to NULL. There is a guaranteed extra element
+ * set to NULL in the @clients list returned to make the iteration easier,
+ * excluding this extra element from the final count.
+ * Caller is responsible to call virAdmClientFree() on each list element,
+ * followed by freeing @clients.
+ */
+int
+virAdmServerListClients(virAdmServerPtr srv,
+ virAdmClientPtr **clients,
+ unsigned int flags)
+{
+ int ret = -1;
+
+ VIR_DEBUG("srv=%p, clients=%p, flags=%x", srv, clients, flags);
+
+ virResetLastError();
+ virCheckFlagsGoto(0, error);
+
+ if (clients)
+ *clients = NULL;
+
+ virCheckAdmServerReturn(srv, -1);
+ if ((ret = remoteAdminServerListClients(srv, clients, flags)) < 0)
+ goto error;
+
+ return ret;
+ error:
+ virDispatchError(NULL);
+ return -1;
+}
diff --git a/src/libvirt_admin_private.syms b/src/libvirt_admin_private.syms
index c407e6e..621b502 100644
--- a/src/libvirt_admin_private.syms
+++ b/src/libvirt_admin_private.syms
@@ -14,6 +14,8 @@ xdr_admin_connect_lookup_server_ret;
xdr_admin_connect_open_args;
xdr_admin_server_get_threadpool_parameters_args;
xdr_admin_server_get_threadpool_parameters_ret;
+xdr_admin_server_list_clients_args;
+xdr_admin_server_list_clients_ret;
xdr_admin_server_set_threadpool_parameters_args;
# datatypes.h
diff --git a/src/libvirt_admin_public.syms b/src/libvirt_admin_public.syms
index 7c4626e..bf6643a 100644
--- a/src/libvirt_admin_public.syms
+++ b/src/libvirt_admin_public.syms
@@ -31,4 +31,5 @@ LIBVIRT_ADMIN_1.3.0 {
virAdmServerFree;
virAdmConnectLookupServer;
virAdmServerSetThreadPoolParameters;
+ virAdmServerListClients;
};
--
2.4.11