*/
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:
*
*/
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);
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
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 {
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;
};
static void virAdmConnectCloseCallbackDataDispose(void *obj);
virClassPtr virAdmServerClass;
+virClassPtr virAdmClientClass;
static void virAdmServerDispose(void *obj);
+static void virAdmClientDispose(void *obj);
static int
virDataTypesOnceInit(void)
DECLARE_CLASS_LOCKABLE(virAdmConnect);
DECLARE_CLASS_LOCKABLE(virAdmConnectCloseCallbackData);
DECLARE_CLASS(virAdmServer);
+ DECLARE_CLASS(virAdmClient);
#undef DECLARE_CLASS_COMMON
#undef DECLARE_CLASS_LOCKABLE
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);
+}
extern virClassPtr virAdmConnectClass;
extern virClassPtr virAdmServerClass;
+extern virClassPtr virAdmClientClass;
# define virCheckConnectReturn(obj, retval) \
do { \
} \
} 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
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:
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,
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
xdr_admin_server_set_threadpool_parameters_args;
# datatypes.h
+virAdmClientClass;
virAdmConnectClass;
virAdmGetServer;
virAdmServerClass;
#
LIBVIRT_ADMIN_1.3.0 {
global:
+ virAdmClientFree;
+ virAdmClientGetID;
+ virAdmClientGetTimestamp;
+ virAdmClientGetTransport;
virAdmConnectOpen;
virAdmConnectClose;
virAdmConnectRef;