Besides ID, the object also stores static data like connection transport and connection timestamp, since once obtained a list of all clients connected to a server, from user's perspective, it would be nice to know whether a given client is remote or local only and when did it connect to the daemon. Along with the object introduction, all necessary client-side methods necessary to work with the object are added as well. Signed-off-by: Erik Skultety <eskultet@xxxxxxxxxx> --- include/libvirt/libvirt-admin.h | 22 ++++++++++ src/admin/admin_protocol.x | 8 ++++ src/admin_protocol-structs | 6 +++ src/datatypes.c | 35 ++++++++++++++++ src/datatypes.h | 47 +++++++++++++++++++++ src/libvirt-admin.c | 90 +++++++++++++++++++++++++++++++++++++++++ src/libvirt_admin_private.syms | 1 + src/libvirt_admin_public.syms | 4 ++ 8 files changed, 213 insertions(+) diff --git a/include/libvirt/libvirt-admin.h b/include/libvirt/libvirt-admin.h index bce6034..f85a7e2 100644 --- a/include/libvirt/libvirt-admin.h +++ b/include/libvirt/libvirt-admin.h @@ -51,6 +51,14 @@ typedef struct _virAdmConnect virAdmConnect; typedef struct _virAdmServer virAdmServer; /** + * virAdmClient: + * + * a virAdmClient is a private structure and client-side representation of + * a remote server's client object (as server sees clients connected to it) + */ +typedef struct _virAdmClient virAdmClient; + +/** * virAdmConnectPtr: * * a virAdmConnectPtr is pointer to a virAdmConnect private structure, @@ -68,6 +76,15 @@ typedef virAdmConnect *virAdmConnectPtr; */ typedef virAdmServer *virAdmServerPtr; +/** + * virAdmClientPtr: + * + * a virAdmClientPtr is a pointer to a virAdmClient structure, + * this is the type used to reference client-side representation of a + * client object throughout all the APIs. + */ +typedef virAdmClient *virAdmClientPtr; + virAdmConnectPtr virAdmConnectOpen(const char *name, unsigned int flags); int virAdmConnectClose(virAdmConnectPtr conn); int virAdmConnectRef(virAdmConnectPtr conn); @@ -182,6 +199,11 @@ int virAdmServerSetThreadPoolParameters(virAdmServerPtr srv, int nparams, unsigned int flags); +unsigned long long virAdmClientGetID(virAdmClientPtr client); +long long virAdmClientGetTimestamp(virAdmClientPtr client); +int virAdmClientGetTransport(virAdmClientPtr client); +int virAdmClientFree(virAdmClientPtr client); + # ifdef __cplusplus } # endif diff --git a/src/admin/admin_protocol.x b/src/admin/admin_protocol.x index c701698..2f302af 100644 --- a/src/admin/admin_protocol.x +++ b/src/admin/admin_protocol.x @@ -72,6 +72,14 @@ struct admin_nonnull_server { admin_nonnull_string name; }; +/* A client which may NOT be NULL */ +struct admin_nonnull_client { + admin_nonnull_server srv; + unsigned hyper id; + hyper timestamp; + unsigned int transport; +}; + /*----- Protocol. -----*/ struct admin_connect_open_args { diff --git a/src/admin_protocol-structs b/src/admin_protocol-structs index 650d31d..d4ccf9e 100644 --- a/src/admin_protocol-structs +++ b/src/admin_protocol-structs @@ -27,6 +27,12 @@ struct admin_typed_param { struct admin_nonnull_server { admin_nonnull_string name; }; +struct admin_nonnull_client { + admin_nonnull_server srv; + uint64_t id; + int64_t timestamp; + u_int transport; +}; struct admin_connect_open_args { u_int flags; }; diff --git a/src/datatypes.c b/src/datatypes.c index 696e8c0..ff0c46f 100644 --- a/src/datatypes.c +++ b/src/datatypes.c @@ -66,7 +66,9 @@ static void virAdmConnectDispose(void *obj); static void virAdmConnectCloseCallbackDataDispose(void *obj); virClassPtr virAdmServerClass; +virClassPtr virAdmClientClass; static void virAdmServerDispose(void *obj); +static void virAdmClientDispose(void *obj); static int virDataTypesOnceInit(void) @@ -98,6 +100,7 @@ virDataTypesOnceInit(void) DECLARE_CLASS_LOCKABLE(virAdmConnect); DECLARE_CLASS_LOCKABLE(virAdmConnectCloseCallbackData); DECLARE_CLASS(virAdmServer); + DECLARE_CLASS(virAdmClient); #undef DECLARE_CLASS_COMMON #undef DECLARE_CLASS_LOCKABLE @@ -962,3 +965,35 @@ virAdmServerDispose(void *obj) VIR_FREE(srv->name); virObjectUnref(srv->conn); } + +virAdmClientPtr +virAdmGetClient(virAdmServerPtr srv, const unsigned long long id, + unsigned long long timestamp, unsigned int transport) +{ + virAdmClientPtr ret = NULL; + + if (virDataTypesInitialize() < 0) + goto error; + + if (!(ret = virObjectNew(virAdmClientClass))) + goto error; + + ret->id = id; + ret->timestamp = timestamp; + ret->transport = transport; + ret->srv = virObjectRef(srv); + + return ret; + error: + virObjectUnref(ret); + return NULL; +} + +static void +virAdmClientDispose(void *obj) +{ + virAdmClientPtr clt = obj; + VIR_DEBUG("release client clt=%p, id=%llu", clt, clt->id); + + virObjectUnref(clt->srv); +} diff --git a/src/datatypes.h b/src/datatypes.h index 92e6863..8ccc7b0 100644 --- a/src/datatypes.h +++ b/src/datatypes.h @@ -43,6 +43,7 @@ extern virClassPtr virStoragePoolClass; extern virClassPtr virAdmConnectClass; extern virClassPtr virAdmServerClass; +extern virClassPtr virAdmClientClass; # define virCheckConnectReturn(obj, retval) \ do { \ @@ -342,6 +343,32 @@ extern virClassPtr virAdmServerClass; } \ } while (0); +# define virCheckAdmClientReturn(obj, retval) \ + do { \ + virAdmClientPtr _clt = (obj); \ + if (!virObjectIsClass(_clt, virAdmClientClass) || \ + !virObjectIsClass(_clt->srv, virAdmServerClass) || \ + !virObjectIsClass(_clt->srv->conn, virAdmConnectClass)) { \ + virReportErrorHelper(VIR_FROM_THIS, VIR_ERR_INVALID_CONN, \ + __FILE__, __FUNCTION__, __LINE__, \ + __FUNCTION__); \ + virDispatchError(NULL); \ + return retval; \ + } \ + } while (0) +# define virCheckAdmClientGoto(obj, label) \ + do { \ + virAdmClientPtr _clt = (obj); \ + if (!virObjectIsClass(_clt, virAdmClientClass) || \ + !virObjectIsClass(_clt->srv, virAdmServerClass) || \ + !virObjectIsClass(_clt->srv->conn, virAdmConnectClass)) { \ + virReportErrorHelper(VIR_FROM_THIS, VIR_ERR_INVALID_CONN, \ + __FILE__, __FUNCTION__, __LINE__, \ + __FUNCTION__); \ + goto label; \ + } \ + } while (0); + /** * VIR_DOMAIN_DEBUG: * @dom: domain @@ -450,6 +477,21 @@ struct _virAdmServer { char *name; /* the server external name */ }; +/** + * _virAdmClient: + * + * Internal structure associated to a client connected to daemon + */ +struct _virAdmClient { + virObject object; + virAdmServerPtr srv; /* pointer to the server client is + * connected to, which also holds a + * reference back to the admin connection + */ + unsigned long long id; /* client's ID */ + long long timestamp; /* connection timestamp */ + unsigned int transport; /* connection type as virClientTransport */ +}; /** * _virDomain: @@ -637,6 +679,11 @@ virAdmConnectPtr virAdmConnectNew(void); virAdmServerPtr virAdmGetServer(virAdmConnectPtr conn, const char *name); +virAdmClientPtr virAdmGetClient(virAdmServerPtr srv, + unsigned long long id, + unsigned long long timestamp, + unsigned int transport); + virConnectCloseCallbackDataPtr virNewConnectCloseCallbackData(void); void virConnectCloseCallbackDataRegister(virConnectCloseCallbackDataPtr close, virConnectPtr conn, diff --git a/src/libvirt-admin.c b/src/libvirt-admin.c index df71649..b45da72 100644 --- a/src/libvirt-admin.c +++ b/src/libvirt-admin.c @@ -600,6 +600,96 @@ int virAdmServerFree(virAdmServerPtr srv) } /** + * virAdmClientGetID: + * @client: a client object + * + * Get client's unique numeric ID. + * + * Returns numeric value used for client's ID or -1 in case of an error. + */ +unsigned long long +virAdmClientGetID(virAdmClientPtr client) +{ + VIR_DEBUG("client=%p", client); + + virResetLastError(); + virCheckAdmClientReturn(client, -1); + return client->id; +} + +/** + * virAdmClientGetTimestamp: + * @client: a client object + * + * Get client's connection time. + * A situation may happen, that some clients had connected prior to the update + * to admin API, thus, libvirt assigns these clients epoch time to express that + * it doesn't know when the client connected. + * + * Returns client's connection timestamp (seconds from epoch in UTC) or 0 + * (epoch time) if libvirt doesn't have any information about client's + * connection time, or -1 in case of an error. + */ +long long +virAdmClientGetTimestamp(virAdmClientPtr client) +{ + VIR_DEBUG("client=%p", client); + + virResetLastError(); + virCheckAdmClientReturn(client, -1); + return client->timestamp; +} + +/** + * virAdmClientGetTransport: + * @client: a client object + * + * Get client's connection transport type. This information can be helpful to + * differentiate between clients connected locally or remotely. An exception to + * this would be SSH which is one of libvirt's supported transports. + * Although SSH creates a channel between two (preferably) remote endpoints, + * the client process libvirt spawns automatically on the remote side will + * still connect to a UNIX socket, thus becoming indistinguishable from any + * other locally connected clients. + * + * Returns integer representation of the connection transport used by client + * @client, this will be one of virClientTransport. + */ +int +virAdmClientGetTransport(virAdmClientPtr client) +{ + VIR_DEBUG("client=%p", client); + + virResetLastError(); + virCheckAdmClientReturn(client, -1); + return client->transport; +} + +/** + * virAdmClientFree: + * @client: a client object + * + * Release the client object. The running instance is kept alive. The data + * structure is freed and should not be used thereafter. + * + * Returns 0 in success, -1 on failure. + */ +int virAdmClientFree(virAdmClientPtr client) +{ + VIR_DEBUG("client=%p", client); + + virResetLastError(); + + if (!client) + return 0; + + virCheckAdmClientReturn(client, -1); + + virObjectUnref(client); + return 0; +} + +/** * virAdmConnectListServers: * @conn: daemon connection reference * @servers: Pointer to a list to store an array containing objects or NULL diff --git a/src/libvirt_admin_private.syms b/src/libvirt_admin_private.syms index b150d8a..c407e6e 100644 --- a/src/libvirt_admin_private.syms +++ b/src/libvirt_admin_private.syms @@ -17,6 +17,7 @@ xdr_admin_server_get_threadpool_parameters_ret; xdr_admin_server_set_threadpool_parameters_args; # datatypes.h +virAdmClientClass; virAdmConnectClass; virAdmGetServer; virAdmServerClass; diff --git a/src/libvirt_admin_public.syms b/src/libvirt_admin_public.syms index 0a16444..7c4626e 100644 --- a/src/libvirt_admin_public.syms +++ b/src/libvirt_admin_public.syms @@ -12,6 +12,10 @@ # LIBVIRT_ADMIN_1.3.0 { global: + virAdmClientFree; + virAdmClientGetID; + virAdmClientGetTimestamp; + virAdmClientGetTransport; virAdmConnectOpen; virAdmConnectClose; virAdmConnectRef; -- 2.4.11 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list