]> xenbits.xensource.com Git - libvirt.git/commitdiff
admin: Introduce virAdmClient client-side object
authorErik Skultety <eskultet@redhat.com>
Wed, 13 Apr 2016 08:35:26 +0000 (10:35 +0200)
committerErik Skultety <eskultet@redhat.com>
Mon, 2 May 2016 20:26:17 +0000 (22:26 +0200)
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@redhat.com>
include/libvirt/libvirt-admin.h
src/admin/admin_protocol.x
src/admin_protocol-structs
src/datatypes.c
src/datatypes.h
src/libvirt-admin.c
src/libvirt_admin_private.syms
src/libvirt_admin_public.syms

index bce6034d97ac03c45a4bb92b76027724e2c9d271..feb94736459181a53c85fdfb65ce227a5209d76a 100644 (file)
@@ -50,6 +50,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:
  *
@@ -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,12 @@ int virAdmServerSetThreadPoolParameters(virAdmServerPtr srv,
                                         int nparams,
                                         unsigned int flags);
 
+/* virAdmClient object accessors */
+unsigned long long virAdmClientGetID(virAdmClientPtr client);
+long long virAdmClientGetTimestamp(virAdmClientPtr client);
+int virAdmClientGetTransport(virAdmClientPtr client);
+int virAdmClientFree(virAdmClientPtr client);
+
 # ifdef __cplusplus
 }
 # endif
index c701698e9cf080b5808db392a4ba916f8bf034ef..2f302af3ab65ecdf72c32e695123e2d39f8ea777 100644 (file)
@@ -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 {
index 650d31d06a2a46bb46dbb1ac3d136b8e67b482b2..d4ccf9ec4d12006f3f9a15b10260b9f0c74c6900 100644 (file)
@@ -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;
 };
index 696e8c046944c33e23a6432c844c8edd9d038d07..ff0c46fab0c2d0d3844b9cf7df59293b2fd7dce3 100644 (file)
@@ -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);
+}
index 92e686371b24a29e5fe5ae15b61dc578e39c2b4c..8ccc7b02eceabf66c528b2e80337bccb219e7641 100644 (file)
@@ -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,
index df71649c2eba0966049646c2ea1da1c74159c082..0d39a795978f08b1d3e23c5488e14742b84638f4 100644 (file)
@@ -599,6 +599,96 @@ int virAdmServerFree(virAdmServerPtr srv)
     return 0;
 }
 
+/**
+ * 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
+ * (this will be one of virClientTransport) or -1 in case of an error.
+ */
+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
index b150d8a86144b853c60b2568811ab59e274265b7..c407e6e5cf982a9517c71285d852b7d4eed2dfe9 100644 (file)
@@ -17,6 +17,7 @@ xdr_admin_server_get_threadpool_parameters_ret;
 xdr_admin_server_set_threadpool_parameters_args;
 
 # datatypes.h
+virAdmClientClass;
 virAdmConnectClass;
 virAdmGetServer;
 virAdmServerClass;
index 0a164448166f270af7b40fe549a0fe73ff541415..7c4626e0c609064aec56a8038c03858ca7253b38 100644 (file)
 #
 LIBVIRT_ADMIN_1.3.0 {
     global:
+        virAdmClientFree;
+        virAdmClientGetID;
+        virAdmClientGetTimestamp;
+        virAdmClientGetTransport;
         virAdmConnectOpen;
         virAdmConnectClose;
         virAdmConnectRef;