mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 13:45:38 +00:00
admin: Introduce adminDaemonConnectListServers API
This API is merely a convenience API, i.e. when managing clients connected to daemon's servers, we should know (convenience) which server the specific client is connected to. This implies a client-side representation of a server along with a basic API to let the administrating client know what servers are actually available on the daemon. Signed-off-by: Erik Skultety <eskultet@redhat.com> Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
This commit is contained in:
parent
c50a834b80
commit
1a07c2efb3
@ -128,7 +128,7 @@ libvirtd_conf_la_LIBADD = $(LIBXML_LIBS)
|
||||
|
||||
noinst_LTLIBRARIES += libvirtd_admin.la
|
||||
libvirtd_admin_la_SOURCES = \
|
||||
admin.c admin.h
|
||||
admin.c admin.h admin_server.c admin_server.h
|
||||
|
||||
libvirtd_admin_la_CFLAGS = \
|
||||
$(AM_CFLAGS) \
|
||||
|
@ -28,6 +28,7 @@
|
||||
|
||||
#include "admin_protocol.h"
|
||||
#include "admin.h"
|
||||
#include "admin_server.h"
|
||||
#include "datatypes.h"
|
||||
#include "viralloc.h"
|
||||
#include "virerror.h"
|
||||
@ -77,6 +78,15 @@ remoteAdmClientInitHook(virNetServerClientPtr client ATTRIBUTE_UNUSED,
|
||||
return priv;
|
||||
}
|
||||
|
||||
/* Helpers */
|
||||
|
||||
static void
|
||||
make_nonnull_server(admin_nonnull_server *srv_dst,
|
||||
virAdmServerPtr srv_src)
|
||||
{
|
||||
ignore_value(VIR_STRDUP_QUIET(srv_dst->name, srv_src->name));
|
||||
}
|
||||
|
||||
/* Functions */
|
||||
static int
|
||||
adminDispatchConnectOpen(virNetServerPtr server ATTRIBUTE_UNUSED,
|
||||
@ -123,4 +133,49 @@ adminConnectGetLibVersion(virNetDaemonPtr dmn ATTRIBUTE_UNUSED,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
adminDispatchConnectListServers(virNetServerPtr server ATTRIBUTE_UNUSED,
|
||||
virNetServerClientPtr client,
|
||||
virNetMessagePtr msg ATTRIBUTE_UNUSED,
|
||||
virNetMessageErrorPtr rerr ATTRIBUTE_UNUSED,
|
||||
admin_connect_list_servers_args *args,
|
||||
admin_connect_list_servers_ret *ret)
|
||||
{
|
||||
virAdmServerPtr *servers = NULL;
|
||||
int nservers = 0;
|
||||
int rv = -1;
|
||||
size_t i;
|
||||
struct daemonAdmClientPrivate *priv =
|
||||
virNetServerClientGetPrivateData(client);
|
||||
|
||||
if ((nservers =
|
||||
adminDaemonListServers(priv->dmn,
|
||||
args->need_results ? &servers : NULL,
|
||||
args->flags)) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (servers && nservers) {
|
||||
if (VIR_ALLOC_N(ret->servers.servers_val, nservers) < 0)
|
||||
goto cleanup;
|
||||
|
||||
ret->servers.servers_len = nservers;
|
||||
for (i = 0; i < nservers; i++)
|
||||
make_nonnull_server(ret->servers.servers_val + i, servers[i]);
|
||||
} else {
|
||||
ret->servers.servers_len = 0;
|
||||
ret->servers.servers_val = NULL;
|
||||
}
|
||||
|
||||
ret->ret = nservers;
|
||||
rv = 0;
|
||||
|
||||
cleanup:
|
||||
if (rv < 0)
|
||||
virNetMessageSaveError(rerr);
|
||||
if (servers && nservers > 0)
|
||||
for (i = 0; i < nservers; i++)
|
||||
virObjectUnref(servers[i]);
|
||||
VIR_FREE(servers);
|
||||
return rv;
|
||||
}
|
||||
#include "admin_dispatch.h"
|
||||
|
73
daemon/admin_server.c
Normal file
73
daemon/admin_server.c
Normal file
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* admin_server.c: admin methods to manage daemons and clients
|
||||
*
|
||||
* Copyright (C) 2016 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Erik Skultety <eskultet@redhat.com>
|
||||
* Martin Kletzander <mkletzan@redhat.com>
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "admin_server.h"
|
||||
#include "datatypes.h"
|
||||
#include "viralloc.h"
|
||||
#include "virerror.h"
|
||||
#include "virlog.h"
|
||||
#include "virnetdaemon.h"
|
||||
#include "virnetserver.h"
|
||||
#include "virstring.h"
|
||||
|
||||
#define VIR_FROM_THIS VIR_FROM_ADMIN
|
||||
|
||||
VIR_LOG_INIT("daemon.admin_server");
|
||||
|
||||
int
|
||||
adminDaemonListServers(virNetDaemonPtr dmn,
|
||||
virAdmServerPtr **servers,
|
||||
unsigned int flags)
|
||||
{
|
||||
int ret = -1;
|
||||
const char **srv_names = NULL;
|
||||
virAdmServerPtr *srvs = NULL;
|
||||
size_t i;
|
||||
ssize_t nsrvs = 0;
|
||||
|
||||
virCheckFlags(0, -1);
|
||||
|
||||
if ((nsrvs = virNetDaemonGetServerNames(dmn, &srv_names)) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (servers) {
|
||||
if (VIR_ALLOC_N(srvs, nsrvs) < 0)
|
||||
goto cleanup;
|
||||
|
||||
for (i = 0; i < nsrvs; i++) {
|
||||
if (!(srvs[i] = virAdmGetServer(NULL, srv_names[i])))
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
*servers = srvs;
|
||||
srvs = NULL;
|
||||
}
|
||||
|
||||
ret = nsrvs;
|
||||
|
||||
cleanup:
|
||||
virObjectListFree(srvs);
|
||||
return ret;
|
||||
}
|
34
daemon/admin_server.h
Normal file
34
daemon/admin_server.h
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* admin_server.h: admin methods to manage daemons and clients
|
||||
*
|
||||
* Copyright (C) 2016 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Erik Skultety <eskultet@redhat.com>
|
||||
* Martin Kletzander <mkletzan@redhat.com>
|
||||
*/
|
||||
|
||||
#ifndef __LIBVIRTD_ADMIN_SERVER_H__
|
||||
# define __LIBVIRTD_ADMIN_SERVER_H__
|
||||
|
||||
# include "rpc/virnetdaemon.h"
|
||||
|
||||
int
|
||||
adminDaemonListServers(virNetDaemonPtr dmn,
|
||||
virAdmServerPtr **servers,
|
||||
unsigned int flags);
|
||||
|
||||
#endif /* __LIBVIRTD_ADMIN_SERVER_H__ */
|
@ -70,9 +70,13 @@ typedef virAdmServer *virAdmServerPtr;
|
||||
|
||||
virAdmConnectPtr virAdmConnectOpen(const char *name, unsigned int flags);
|
||||
int virAdmConnectClose(virAdmConnectPtr conn);
|
||||
|
||||
int virAdmConnectRef(virAdmConnectPtr conn);
|
||||
int virAdmConnectIsAlive(virAdmConnectPtr conn);
|
||||
int virAdmServerFree(virAdmServerPtr srv);
|
||||
|
||||
int virAdmConnectListServers(virAdmConnectPtr dmn,
|
||||
virAdmServerPtr **servers,
|
||||
unsigned int flags);
|
||||
|
||||
int virAdmGetVersion(unsigned long long *libVer);
|
||||
|
||||
@ -100,6 +104,8 @@ int virAdmConnectRegisterCloseCallback(virAdmConnectPtr conn,
|
||||
int virAdmConnectUnregisterCloseCallback(virAdmConnectPtr conn,
|
||||
virAdmConnectCloseFunc cb);
|
||||
|
||||
const char *virAdmServerGetName(virAdmServerPtr srv);
|
||||
|
||||
# ifdef __cplusplus
|
||||
}
|
||||
# endif
|
||||
|
@ -10,6 +10,7 @@ gnulib/lib/gai_strerror.c
|
||||
gnulib/lib/regcomp.c
|
||||
src/access/viraccessdriverpolkit.c
|
||||
src/access/viraccessmanager.c
|
||||
src/admin/admin_remote.c
|
||||
src/bhyve/bhyve_command.c
|
||||
src/bhyve/bhyve_device.c
|
||||
src/bhyve/bhyve_driver.c
|
||||
|
@ -55,6 +55,16 @@ struct admin_connect_get_lib_version_ret {
|
||||
unsigned hyper libVer;
|
||||
};
|
||||
|
||||
struct admin_connect_list_servers_args {
|
||||
unsigned int need_results;
|
||||
unsigned int flags;
|
||||
};
|
||||
|
||||
struct admin_connect_list_servers_ret {
|
||||
admin_nonnull_server servers<ADMIN_SERVER_LIST_MAX>;
|
||||
unsigned int ret;
|
||||
};
|
||||
|
||||
/* Define the program number, protocol version and procedure numbers here. */
|
||||
const ADMIN_PROGRAM = 0x06900690;
|
||||
const ADMIN_PROTOCOL_VERSION = 1;
|
||||
@ -90,5 +100,11 @@ enum admin_procedure {
|
||||
/**
|
||||
* @generate: both
|
||||
*/
|
||||
ADMIN_PROC_CONNECT_GET_LIB_VERSION = 3
|
||||
ADMIN_PROC_CONNECT_GET_LIB_VERSION = 3,
|
||||
|
||||
/**
|
||||
* @generate: none
|
||||
* @priority: high
|
||||
*/
|
||||
ADMIN_PROC_CONNECT_LIST_SERVERS = 4
|
||||
};
|
||||
|
@ -47,6 +47,14 @@ remoteAdminPrivDispose(void *opaque)
|
||||
}
|
||||
|
||||
|
||||
/* Helpers */
|
||||
static virAdmServerPtr
|
||||
get_nonnull_server(virAdmConnectPtr conn, admin_nonnull_server server)
|
||||
{
|
||||
return virAdmGetServer(conn, server.name);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
callFull(virAdmConnectPtr conn ATTRIBUTE_UNUSED,
|
||||
remoteAdminPrivPtr priv,
|
||||
@ -214,3 +222,66 @@ remoteAdminPrivNew(const char *sock_path)
|
||||
virObjectUnref(priv);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
remoteAdminConnectListServers(virAdmConnectPtr conn,
|
||||
virAdmServerPtr **servers,
|
||||
unsigned int flags)
|
||||
{
|
||||
int rv = -1;
|
||||
size_t i;
|
||||
virAdmServerPtr *tmp_srvs = NULL;
|
||||
remoteAdminPrivPtr priv = conn->privateData;
|
||||
admin_connect_list_servers_args args;
|
||||
admin_connect_list_servers_ret ret;
|
||||
|
||||
args.need_results = !!servers;
|
||||
args.flags = flags;
|
||||
|
||||
memset(&ret, 0, sizeof(ret));
|
||||
virObjectLock(priv);
|
||||
|
||||
if (call(conn,
|
||||
0,
|
||||
ADMIN_PROC_CONNECT_LIST_SERVERS,
|
||||
(xdrproc_t) xdr_admin_connect_list_servers_args,
|
||||
(char *) &args,
|
||||
(xdrproc_t) xdr_admin_connect_list_servers_ret,
|
||||
(char *) &ret) == -1)
|
||||
goto done;
|
||||
|
||||
if (ret.servers.servers_len > ADMIN_SERVER_LIST_MAX) {
|
||||
virReportError(VIR_ERR_RPC,
|
||||
_("Too many servers '%d' for limit '%d'"),
|
||||
ret.servers.servers_len, ADMIN_SERVER_LIST_MAX);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (servers) {
|
||||
if (VIR_ALLOC_N(tmp_srvs, ret.servers.servers_len + 1) < 0)
|
||||
goto cleanup;
|
||||
|
||||
for (i = 0; i < ret.servers.servers_len; i++) {
|
||||
tmp_srvs[i] = get_nonnull_server(conn, ret.servers.servers_val[i]);
|
||||
if (!tmp_srvs[i])
|
||||
goto cleanup;
|
||||
}
|
||||
*servers = tmp_srvs;
|
||||
tmp_srvs = NULL;
|
||||
}
|
||||
|
||||
rv = ret.ret;
|
||||
|
||||
cleanup:
|
||||
if (tmp_srvs) {
|
||||
for (i = 0; i < ret.servers.servers_len; i++)
|
||||
virObjectUnref(tmp_srvs[i]);
|
||||
VIR_FREE(tmp_srvs);
|
||||
}
|
||||
|
||||
xdr_free((xdrproc_t) xdr_admin_connect_list_servers_ret, (char *) &ret);
|
||||
|
||||
done:
|
||||
virObjectUnlock(priv);
|
||||
return rv;
|
||||
}
|
||||
|
@ -8,8 +8,20 @@ struct admin_connect_open_args {
|
||||
struct admin_connect_get_lib_version_ret {
|
||||
uint64_t libVer;
|
||||
};
|
||||
struct admin_connect_list_servers_args {
|
||||
u_int need_results;
|
||||
u_int flags;
|
||||
};
|
||||
struct admin_connect_list_servers_ret {
|
||||
struct {
|
||||
u_int servers_len;
|
||||
admin_nonnull_server * servers_val;
|
||||
} servers;
|
||||
u_int ret;
|
||||
};
|
||||
enum admin_procedure {
|
||||
ADMIN_PROC_CONNECT_OPEN = 1,
|
||||
ADMIN_PROC_CONNECT_CLOSE = 2,
|
||||
ADMIN_PROC_CONNECT_GET_LIB_VERSION = 3,
|
||||
ADMIN_PROC_CONNECT_LIST_SERVERS = 4,
|
||||
};
|
||||
|
@ -549,7 +549,86 @@ int virAdmConnectGetLibVersion(virAdmConnectPtr conn,
|
||||
goto error;
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
virDispatchError(NULL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* virAdmServerGetName:
|
||||
* @srv: a server object
|
||||
*
|
||||
* Get the public name for specified server
|
||||
*
|
||||
* Returns a pointer to the name or NULL. The string doesn't need to be
|
||||
* deallocated since its lifetime will be the same as the server object.
|
||||
*/
|
||||
const char *
|
||||
virAdmServerGetName(virAdmServerPtr srv)
|
||||
{
|
||||
VIR_DEBUG("server=%p", srv);
|
||||
|
||||
virResetLastError();
|
||||
virCheckAdmServerReturn(srv, NULL);
|
||||
|
||||
return srv->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* virAdmServerFree:
|
||||
* @srv: server object
|
||||
*
|
||||
* Release the server object. The running instance is kept alive.
|
||||
* The data structure is freed and should not be used thereafter.
|
||||
*
|
||||
* Returns 0 on success, -1 on failure.
|
||||
*/
|
||||
int virAdmServerFree(virAdmServerPtr srv)
|
||||
{
|
||||
VIR_DEBUG("server=%p", srv);
|
||||
|
||||
virResetLastError();
|
||||
virCheckAdmServerReturn(srv, -1);
|
||||
|
||||
virObjectUnref(srv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* virAdmConnectListServers:
|
||||
* @conn: daemon connection reference
|
||||
* @servers: Pointer to a list to store an array containing objects or NULL
|
||||
* if the list is not required (number of servers only)
|
||||
* @flags: bitwise-OR of virAdmConnectListServersFlags
|
||||
*
|
||||
* Collect list of all servers provided by daemon the client is connected to.
|
||||
*
|
||||
* Returns the number of servers available on daemon side or -1 in case of a
|
||||
* failure, setting @servers to NULL. There is a guaranteed extra element set
|
||||
* to NULL in the @servers list returned to make the iteration easier, excluding
|
||||
* this extra element from the final count.
|
||||
* Caller is responsible to call virAdmServerFree() on each list element,
|
||||
* followed by freeing @servers.
|
||||
*/
|
||||
int
|
||||
virAdmConnectListServers(virAdmConnectPtr conn,
|
||||
virAdmServerPtr **servers,
|
||||
unsigned int flags)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
VIR_DEBUG("conn=%p, servers=%p, flags=%x", conn, servers, flags);
|
||||
|
||||
virResetLastError();
|
||||
|
||||
if (servers)
|
||||
*servers = NULL;
|
||||
|
||||
virCheckAdmConnectReturn(conn, -1);
|
||||
if ((ret = remoteAdminConnectListServers(conn, servers, flags)) < 0)
|
||||
goto error;
|
||||
|
||||
return ret;
|
||||
error:
|
||||
virDispatchError(NULL);
|
||||
return -1;
|
||||
|
@ -7,6 +7,8 @@
|
||||
|
||||
# admin/admin_protocol.x
|
||||
xdr_admin_connect_get_lib_version_ret;
|
||||
xdr_admin_connect_list_servers_args;
|
||||
xdr_admin_connect_list_servers_ret;
|
||||
xdr_admin_connect_open_args;
|
||||
|
||||
# datatypes.h
|
||||
|
@ -21,4 +21,7 @@ LIBVIRT_ADMIN_1.3.0 {
|
||||
virAdmConnectGetLibVersion;
|
||||
virAdmConnectRegisterCloseCallback;
|
||||
virAdmConnectUnregisterCloseCallback;
|
||||
virAdmConnectListServers;
|
||||
virAdmServerGetName;
|
||||
virAdmServerFree;
|
||||
};
|
||||
|
@ -190,6 +190,45 @@ virNetDaemonGetServer(virNetDaemonPtr dmn,
|
||||
return srv;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Returns number of names allocated in *servers, on error sets
|
||||
* *servers to NULL and returns -1. List of *servers must be free()d,
|
||||
* but not the items in it (similarly to virHashGetItems).
|
||||
*/
|
||||
ssize_t
|
||||
virNetDaemonGetServerNames(virNetDaemonPtr dmn,
|
||||
const char ***servers)
|
||||
{
|
||||
virHashKeyValuePairPtr items = NULL;
|
||||
size_t nservers = 0;
|
||||
ssize_t ret = -1;
|
||||
size_t i;
|
||||
|
||||
*servers = NULL;
|
||||
|
||||
virObjectLock(dmn);
|
||||
|
||||
items = virHashGetItems(dmn->servers, NULL);
|
||||
if (!items)
|
||||
goto cleanup;
|
||||
|
||||
for (i = 0; items[i].key; i++) {
|
||||
if (VIR_APPEND_ELEMENT(*servers, nservers, items[i].key) < 0)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ret = nservers;
|
||||
|
||||
cleanup:
|
||||
if (ret < 0)
|
||||
VIR_FREE(*servers);
|
||||
VIR_FREE(items);
|
||||
virObjectUnlock(dmn);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
virNetServerPtr
|
||||
virNetDaemonAddServerPostExec(virNetDaemonPtr dmn,
|
||||
const char *serverName,
|
||||
|
@ -83,5 +83,6 @@ bool virNetDaemonHasClients(virNetDaemonPtr dmn);
|
||||
|
||||
virNetServerPtr virNetDaemonGetServer(virNetDaemonPtr dmn,
|
||||
const char *serverName);
|
||||
ssize_t virNetDaemonGetServerNames(virNetDaemonPtr dmn, const char ***servers);
|
||||
|
||||
#endif /* __VIR_NET_DAEMON_H__ */
|
||||
|
Loading…
Reference in New Issue
Block a user