From caa16d31688725b6031e155d8c1e20d5008559ba Mon Sep 17 00:00:00 2001 From: Erik Skultety Date: Mon, 23 Nov 2015 12:41:32 +0100 Subject: [PATCH] admin: Introduce virAdmServerGethreadPoolParameters New API to retrieve current server workerpool specs. Since it uses typed parameters, more specs to retrieve can be further included in the pool of supported ones. Signed-off-by: Erik Skultety --- daemon/admin.c | 45 ++++++++++++++++++++++ daemon/admin_server.c | 67 +++++++++++++++++++++++++++++++++ daemon/admin_server.h | 6 +++ include/libvirt/libvirt-admin.h | 6 +++ po/POTFILES.in | 1 + src/admin/admin_protocol.x | 19 +++++++++- src/admin/admin_remote.c | 43 +++++++++++++++++++++ src/admin_protocol-structs | 11 ++++++ src/libvirt-admin.c | 47 +++++++++++++++++++++++ src/libvirt_admin_private.syms | 2 + src/libvirt_admin_public.syms | 1 + src/rpc/virnetserver.c | 22 +++++++++++ src/rpc/virnetserver.h | 8 ++++ 13 files changed, 277 insertions(+), 1 deletion(-) diff --git a/daemon/admin.c b/daemon/admin.c index 3169cddb58..4589eb618f 100644 --- a/daemon/admin.c +++ b/daemon/admin.c @@ -37,6 +37,7 @@ #include "virnetserver.h" #include "virstring.h" #include "virthreadjob.h" +#include "virtypedparam.h" #define VIR_FROM_THIS VIR_FROM_ADMIN @@ -133,4 +134,48 @@ adminConnectGetLibVersion(virNetDaemonPtr dmn ATTRIBUTE_UNUSED, return 0; } +static int +adminDispatchServerGetThreadpoolParameters(virNetServerPtr server ATTRIBUTE_UNUSED, + virNetServerClientPtr client, + virNetMessagePtr msg ATTRIBUTE_UNUSED, + virNetMessageErrorPtr rerr, + struct admin_server_get_threadpool_parameters_args *args, + struct admin_server_get_threadpool_parameters_ret *ret) +{ + int rv = -1; + virNetServerPtr srv = NULL; + virTypedParameterPtr params = NULL; + int nparams = 0; + struct daemonAdmClientPrivate *priv = + virNetServerClientGetPrivateData(client); + + if (!(srv = virNetDaemonGetServer(priv->dmn, args->srv.name))) + goto cleanup; + + if (adminServerGetThreadPoolParameters(srv, ¶ms, &nparams, + args->flags) < 0) + goto cleanup; + + if (nparams > ADMIN_SERVER_THREADPOOL_PARAMETERS_MAX) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Number of threadpool parameters %d exceeds max " + "allowed limit: %d"), nparams, + ADMIN_SERVER_THREADPOOL_PARAMETERS_MAX); + goto cleanup; + } + + if (virTypedParamsSerialize(params, nparams, + (virTypedParameterRemotePtr *) &ret->params.params_val, + &ret->params.params_len, 0) < 0) + goto cleanup; + + rv = 0; + cleanup: + if (rv < 0) + virNetMessageSaveError(rerr); + + virTypedParamsFree(params, nparams); + virObjectUnref(srv); + return rv; +} #include "admin_dispatch.h" diff --git a/daemon/admin_server.c b/daemon/admin_server.c index 1d30ea5079..10c00f6386 100644 --- a/daemon/admin_server.c +++ b/daemon/admin_server.c @@ -31,6 +31,7 @@ #include "virnetdaemon.h" #include "virnetserver.h" #include "virstring.h" +#include "virthreadpool.h" #define VIR_FROM_THIS VIR_FROM_ADMIN @@ -68,3 +69,69 @@ adminConnectLookupServer(virNetDaemonPtr dmn, return virNetDaemonGetServer(dmn, name); } + +int +adminServerGetThreadPoolParameters(virNetServerPtr srv, + virTypedParameterPtr *params, + int *nparams, + unsigned int flags) +{ + int ret = -1; + int maxparams = 0; + size_t minWorkers; + size_t maxWorkers; + size_t nWorkers; + size_t freeWorkers; + size_t nPrioWorkers; + size_t jobQueueDepth; + virTypedParameterPtr tmpparams = NULL; + + virCheckFlags(0, -1); + + if (virNetServerGetThreadPoolParameters(srv, &minWorkers, &maxWorkers, + &nWorkers, &freeWorkers, + &nPrioWorkers, + &jobQueueDepth) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Unable to retrieve threadpool parameters")); + goto cleanup; + } + + if (virTypedParamsAddUInt(&tmpparams, nparams, + &maxparams, VIR_THREADPOOL_WORKERS_MIN, + minWorkers) < 0) + goto cleanup; + + if (virTypedParamsAddUInt(&tmpparams, nparams, + &maxparams, VIR_THREADPOOL_WORKERS_MAX, + maxWorkers) < 0) + goto cleanup; + + if (virTypedParamsAddUInt(&tmpparams, nparams, + &maxparams, VIR_THREADPOOL_WORKERS_CURRENT, + nWorkers) < 0) + goto cleanup; + + if (virTypedParamsAddUInt(&tmpparams, nparams, + &maxparams, VIR_THREADPOOL_WORKERS_FREE, + freeWorkers) < 0) + goto cleanup; + + if (virTypedParamsAddUInt(&tmpparams, nparams, + &maxparams, VIR_THREADPOOL_WORKERS_PRIORITY, + nPrioWorkers) < 0) + goto cleanup; + + if (virTypedParamsAddUInt(&tmpparams, nparams, + &maxparams, VIR_THREADPOOL_JOB_QUEUE_DEPTH, + jobQueueDepth) < 0) + goto cleanup; + + *params = tmpparams; + tmpparams = NULL; + ret = 0; + + cleanup: + virTypedParamsFree(tmpparams, *nparams); + return ret; +} diff --git a/daemon/admin_server.h b/daemon/admin_server.h index 9d0adf02c7..2ddaecc707 100644 --- a/daemon/admin_server.h +++ b/daemon/admin_server.h @@ -35,4 +35,10 @@ virNetServerPtr adminConnectLookupServer(virNetDaemonPtr dmn, const char *name, unsigned int flags); +int +adminServerGetThreadPoolParameters(virNetServerPtr srv, + virTypedParameterPtr *params, + int *nparams, + unsigned int flags); + #endif /* __LIBVIRTD_ADMIN_SERVER_H__ */ diff --git a/include/libvirt/libvirt-admin.h b/include/libvirt/libvirt-admin.h index 0cce710a2f..bb13250513 100644 --- a/include/libvirt/libvirt-admin.h +++ b/include/libvirt/libvirt-admin.h @@ -171,6 +171,12 @@ virAdmServerPtr virAdmConnectLookupServer(virAdmConnectPtr conn, # define VIR_THREADPOOL_JOB_QUEUE_DEPTH "jobQueueDepth" +/* Tunables for a server workerpool */ +int virAdmServerGetThreadPoolParameters(virAdmServerPtr srv, + virTypedParameterPtr *params, + int *nparams, + unsigned int flags); + # ifdef __cplusplus } # endif diff --git a/po/POTFILES.in b/po/POTFILES.in index ed82aca7c6..2f530796e6 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -1,5 +1,6 @@ daemon/admin.c daemon/admin_dispatch.h +daemon/admin_server.c daemon/libvirtd-config.c daemon/libvirtd.c daemon/qemu_dispatch.h diff --git a/src/admin/admin_protocol.x b/src/admin/admin_protocol.x index 57dbb6b103..b1093d8889 100644 --- a/src/admin/admin_protocol.x +++ b/src/admin/admin_protocol.x @@ -36,6 +36,9 @@ const ADMIN_STRING_MAX = 4194304; /* Upper limit on list of servers */ const ADMIN_SERVER_LIST_MAX = 16384; +/* Upper limit on number of threadpool parameters */ +const ADMIN_SERVER_THREADPOOL_PARAMETERS_MAX = 32; + /* A long string, which may NOT be NULL. */ typedef string admin_nonnull_string; @@ -98,6 +101,15 @@ struct admin_connect_lookup_server_ret { admin_nonnull_server srv; }; +struct admin_server_get_threadpool_parameters_args { + admin_nonnull_server srv; + unsigned int flags; +}; + +struct admin_server_get_threadpool_parameters_ret { + admin_typed_param params; +}; + /* Define the program number, protocol version and procedure numbers here. */ const ADMIN_PROGRAM = 0x06900690; const ADMIN_PROTOCOL_VERSION = 1; @@ -143,5 +155,10 @@ enum admin_procedure { /** * @generate: both */ - ADMIN_PROC_CONNECT_LOOKUP_SERVER = 5 + ADMIN_PROC_CONNECT_LOOKUP_SERVER = 5, + + /** + * @generate: none + */ + ADMIN_PROC_SERVER_GET_THREADPOOL_PARAMETERS = 6 }; diff --git a/src/admin/admin_remote.c b/src/admin/admin_remote.c index 21e0dd30c4..ac38ce91a9 100644 --- a/src/admin/admin_remote.c +++ b/src/admin/admin_remote.c @@ -22,6 +22,7 @@ #include #include +#include "virtypedparam.h" #include "admin_protocol.h" typedef struct _remoteAdminPriv remoteAdminPriv; @@ -54,6 +55,11 @@ get_nonnull_server(virAdmConnectPtr conn, admin_nonnull_server server) return virAdmGetServer(conn, server.name); } +static void +make_nonnull_server(admin_nonnull_server *srv_dst, virAdmServerPtr srv_src) +{ + srv_dst->name = srv_src->name; +} static int callFull(virAdmConnectPtr conn ATTRIBUTE_UNUSED, @@ -224,3 +230,40 @@ remoteAdminPrivNew(const char *sock_path) virObjectUnref(priv); return NULL; } + +static int +remoteAdminServerGetThreadPoolParameters(virAdmServerPtr srv, + virTypedParameterPtr *params, + int *nparams, + unsigned int flags) +{ + int rv = -1; + remoteAdminPrivPtr priv = srv->conn->privateData; + admin_server_get_threadpool_parameters_args args; + admin_server_get_threadpool_parameters_ret ret; + + args.flags = flags; + make_nonnull_server(&args.srv, srv); + + memset(&ret, 0, sizeof(ret)); + virObjectLock(priv); + + if (call(srv->conn, 0, ADMIN_PROC_SERVER_GET_THREADPOOL_PARAMETERS, + (xdrproc_t)xdr_admin_server_get_threadpool_parameters_args, (char *) &args, + (xdrproc_t)xdr_admin_server_get_threadpool_parameters_ret, (char *) &ret) == -1) + goto cleanup; + + if (virTypedParamsDeserialize((virTypedParameterRemotePtr) ret.params.params_val, + ret.params.params_len, + ADMIN_SERVER_THREADPOOL_PARAMETERS_MAX, + params, + nparams) < 0) + goto cleanup; + + rv = 0; + xdr_free((xdrproc_t)xdr_admin_server_get_threadpool_parameters_ret, (char *) &ret); + + cleanup: + virObjectUnlock(priv); + return rv; +} diff --git a/src/admin_protocol-structs b/src/admin_protocol-structs index 26c84439f4..c4e679a900 100644 --- a/src/admin_protocol-structs +++ b/src/admin_protocol-structs @@ -51,10 +51,21 @@ struct admin_connect_lookup_server_args { struct admin_connect_lookup_server_ret { admin_nonnull_server srv; }; +struct admin_server_get_threadpool_parameters_args { + admin_nonnull_server srv; + u_int flags; +}; +struct admin_server_get_threadpool_parameters_ret { + struct { + u_int params_len; + admin_typed_param * params_val; + } params; +}; 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, ADMIN_PROC_CONNECT_LOOKUP_SERVER = 5, + ADMIN_PROC_SERVER_GET_THREADPOOL_PARAMETERS = 6, }; diff --git a/src/libvirt-admin.c b/src/libvirt-admin.c index 6577c87693..07d46c4db5 100644 --- a/src/libvirt-admin.c +++ b/src/libvirt-admin.c @@ -674,3 +674,50 @@ virAdmConnectLookupServer(virAdmConnectPtr conn, virDispatchError(NULL); return ret; } + +/** + * virAdmServerGetThreadPoolParameters: + * @srv: a valid server object reference + * @params: pointer to a list of typed parameters which will be allocated + * to store all returned parameters + * @nparams: pointer which will hold the number of params returned in @params + * @flags: extra flags; not used yet, so callers should always pass 0 + * + * Retrieves threadpool parameters from @srv. Upon successful completion, + * @params will be allocated automatically to hold all returned data, setting + * @nparams accordingly. + * When extracting parameters from @params, following search keys are + * supported: + * VIR_THREADPOOL_WORKERS_MIN + * VIR_THREADPOOL_WORKERS_MAX + * VIR_THREADPOOL_WORKERS_PRIORITY + * VIR_THREADPOOL_WORKERS_FREE + * VIR_THREADPOOL_WORKERS_CURRENT + * + * Returns 0 on success, -1 in case of an error. + */ +int +virAdmServerGetThreadPoolParameters(virAdmServerPtr srv, + virTypedParameterPtr *params, + int *nparams, + unsigned int flags) +{ + int ret = -1; + + VIR_DEBUG("srv=%p, params=%p, nparams=%p, flags=%x", + srv, params, nparams, flags); + + virResetLastError(); + + virCheckAdmServerReturn(srv, -1); + virCheckNonNullArgGoto(params, error); + + if ((ret = remoteAdminServerGetThreadPoolParameters(srv, params, nparams, + flags)) < 0) + goto error; + + return ret; + error: + virDispatchError(NULL); + return -1; +} diff --git a/src/libvirt_admin_private.syms b/src/libvirt_admin_private.syms index 268f1e6f2f..b05067c7e3 100644 --- a/src/libvirt_admin_private.syms +++ b/src/libvirt_admin_private.syms @@ -12,6 +12,8 @@ xdr_admin_connect_list_servers_ret; xdr_admin_connect_lookup_server_args; xdr_admin_connect_lookup_server_ret; xdr_admin_connect_open_args; +xdr_admin_server_get_threadpool_parameters_args; +xdr_admin_server_get_threadpool_parameters_ret; # datatypes.h virAdmConnectClass; diff --git a/src/libvirt_admin_public.syms b/src/libvirt_admin_public.syms index 58d085e1f1..0a12b5fb3f 100644 --- a/src/libvirt_admin_public.syms +++ b/src/libvirt_admin_public.syms @@ -23,6 +23,7 @@ LIBVIRT_ADMIN_1.3.0 { virAdmConnectUnregisterCloseCallback; virAdmConnectListServers; virAdmServerGetName; + virAdmServerGetThreadPoolParameters; virAdmServerFree; virAdmConnectLookupServer; }; diff --git a/src/rpc/virnetserver.c b/src/rpc/virnetserver.c index cf48e50603..3878547700 100644 --- a/src/rpc/virnetserver.c +++ b/src/rpc/virnetserver.c @@ -877,3 +877,25 @@ virNetServerGetName(virNetServerPtr srv) { return srv->name; } + +int +virNetServerGetThreadPoolParameters(virNetServerPtr srv, + size_t *minWorkers, + size_t *maxWorkers, + size_t *nWorkers, + size_t *freeWorkers, + size_t *nPrioWorkers, + size_t *jobQueueDepth) +{ + virObjectLock(srv); + + *minWorkers = virThreadPoolGetMinWorkers(srv->workers); + *maxWorkers = virThreadPoolGetMaxWorkers(srv->workers); + *freeWorkers = virThreadPoolGetFreeWorkers(srv->workers); + *nWorkers = virThreadPoolGetCurrentWorkers(srv->workers); + *nPrioWorkers = virThreadPoolGetPriorityWorkers(srv->workers); + *jobQueueDepth = virThreadPoolGetJobQueueDepth(srv->workers); + + virObjectUnlock(srv); + return 0; +} diff --git a/src/rpc/virnetserver.h b/src/rpc/virnetserver.h index aa244401a2..6f17d1cc4c 100644 --- a/src/rpc/virnetserver.h +++ b/src/rpc/virnetserver.h @@ -89,4 +89,12 @@ int virNetServerStart(virNetServerPtr srv); const char *virNetServerGetName(virNetServerPtr srv); +int virNetServerGetThreadPoolParameters(virNetServerPtr srv, + size_t *minWorkers, + size_t *maxWorkers, + size_t *nWorkers, + size_t *freeWorkers, + size_t *nPrioWorkers, + size_t *jobQueueDepth); + #endif /* __VIR_NET_SERVER_H__ */