admin: Introduce virAdmClient client-side object

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>
This commit is contained in:
Erik Skultety 2016-04-13 10:35:26 +02:00
parent a32135b3b1
commit 324945d99b
8 changed files with 214 additions and 0 deletions

View 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

View 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 {

View 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;
};

View 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);
}

View 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,

View 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

View 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;

View File

@ -12,6 +12,10 @@
#
LIBVIRT_ADMIN_1.3.0 {
global:
virAdmClientFree;
virAdmClientGetID;
virAdmClientGetTimestamp;
virAdmClientGetTransport;
virAdmConnectOpen;
virAdmConnectClose;
virAdmConnectRef;