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. --- daemon/admin.c | 60 +++++++++++++++++++++++++++++++++++ daemon/admin_server.c | 69 +++++++++++++++++++++++++++++++++++++++++ daemon/admin_server.h | 6 ++++ include/libvirt/libvirt-admin.h | 6 ++++ src/admin/admin_protocol.x | 20 ++++++++++-- src/admin/admin_remote.c | 43 +++++++++++++++++++++++++ src/admin_protocol-structs | 11 +++++++ src/libvirt-admin.c | 46 +++++++++++++++++++++++++++ src/libvirt_admin_private.syms | 2 ++ src/libvirt_admin_public.syms | 1 + src/rpc/virnetserver.c | 22 +++++++++++++ src/rpc/virnetserver.h | 13 ++++++++ 12 files changed, 296 insertions(+), 3 deletions(-) diff --git a/daemon/admin.c b/daemon/admin.c index 45b1190..8dc396e 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 @@ -204,4 +205,63 @@ adminDispatchConnectServerLookupByName(virNetServerPtr server ATTRIBUTE_UNUSED, virObjectUnref(srv); return rv; } + +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->server.name))) { + virReportError(VIR_ERR_NO_SERVER, + _("no server with matching name '%s' found"), + args->server.name); + goto cleanup; + } + + if (adminDaemonGetThreadPoolParameters(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 (nparams) { + if (VIR_ALLOC_N(ret->params.params_val, nparams) < 0) + goto cleanup; + + ret->params.params_len = nparams; + + if (virTypedParamsSerialize(params, nparams, + (virTypedParameterRemotePtr *) &ret->params.params_val, + &ret->params.params_len, 0) < 0) + goto cleanup; + } else { + ret->params.params_len = 0; + ret->params.params_val = NULL; + } + + 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 de8bc71..861a98c 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 @@ -89,3 +90,71 @@ adminDaemonLookupServerByName(virNetDaemonPtr dmn, virObjectUnref(srv); return virAdmGetServer(NULL, name); } + +int +adminDaemonGetThreadPoolParameters(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: + if (tmpparams) + virTypedParamsFree(tmpparams, *nparams); + + return ret; +} diff --git a/daemon/admin_server.h b/daemon/admin_server.h index 385c3e4..7794bf1 100644 --- a/daemon/admin_server.h +++ b/daemon/admin_server.h @@ -35,4 +35,10 @@ virAdmServerPtr adminDaemonLookupServerByName(virNetDaemonPtr dmn, const char *name); +int +adminDaemonGetThreadPoolParameters(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 e12c5ce..b96545b 100644 --- a/include/libvirt/libvirt-admin.h +++ b/include/libvirt/libvirt-admin.h @@ -169,6 +169,12 @@ virAdmServerPtr virAdmConnectServerLookupByName(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/src/admin/admin_protocol.x b/src/admin/admin_protocol.x index 9d56a69..ed7bf67 100644 --- a/src/admin/admin_protocol.x +++ b/src/admin/admin_protocol.x @@ -36,8 +36,8 @@ const ADMIN_STRING_MAX = 4194304; /* Upper limit on list of servers */ const ADMIN_SERVER_LIST_MAX = 16384; -/* Upper limit on number of threadpool stats */ -const ADMIN_SERVER_THREADPOOL_STATS_MAX = 32; +/* 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<ADMIN_STRING_MAX>; @@ -100,6 +100,15 @@ struct admin_connect_server_lookup_by_name_ret { admin_nonnull_server server; }; +struct admin_server_get_threadpool_parameters_args { + admin_nonnull_server server; + unsigned int flags; +}; + +struct admin_server_get_threadpool_parameters_ret { + admin_typed_param params<ADMIN_SERVER_THREADPOOL_PARAMETERS_MAX>; +}; + /* Define the program number, protocol version and procedure numbers here. */ const ADMIN_PROGRAM = 0x06900690; const ADMIN_PROTOCOL_VERSION = 1; @@ -146,5 +155,10 @@ enum admin_procedure { /** * @generate: none */ - ADMIN_PROC_CONNECT_SERVER_LOOKUP_BY_NAME = 5 + ADMIN_PROC_CONNECT_SERVER_LOOKUP_BY_NAME = 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 570dce4..2717a17 100644 --- a/src/admin/admin_remote.c +++ b/src/admin/admin_remote.c @@ -22,6 +22,7 @@ #include <config.h> #include <rpc/rpc.h> +#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, @@ -314,3 +320,40 @@ remoteAdminConnectServerLookupByName(virAdmConnectPtr conn, virObjectUnlock(priv); return rv; } + +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.server, 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 141de25..d0bc367 100644 --- a/src/admin_protocol-structs +++ b/src/admin_protocol-structs @@ -50,10 +50,21 @@ struct admin_connect_server_lookup_by_name_args { struct admin_connect_server_lookup_by_name_ret { admin_nonnull_server server; }; +struct admin_server_get_threadpool_parameters_args { + admin_nonnull_server server; + 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_SERVER_LOOKUP_BY_NAME = 5, + ADMIN_PROC_SERVER_GET_THREADPOOL_PARAMETERS = 6, }; diff --git a/src/libvirt-admin.c b/src/libvirt-admin.c index d09c015..6165159 100644 --- a/src/libvirt-admin.c +++ b/src/libvirt-admin.c @@ -664,3 +664,49 @@ virAdmConnectServerLookupByName(virAdmConnectPtr conn, virDispatchError(NULL); return NULL; } + +/** + * virAdmServerGetThreadPoolParameters: + * @srv: a valid server object reference + * @params: a pointer which will be allocated to store all returned parameters + * @nparams: a pointer which will hold the number of params returned in @params + * @flags: extra flags for virAdmServerGetThreadPoolStatsFlags + * + * This methods retrieves threadpool parameters from @srv. Upon successful + * completion, @params will be allocated automatically to hold all returned + * params and 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 cdd2203..7d3067f 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_open_args; xdr_admin_connect_server_lookup_by_name_args; xdr_admin_connect_server_lookup_by_name_ret; +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 84936c2..e89ad75 100644 --- a/src/libvirt_admin_public.syms +++ b/src/libvirt_admin_public.syms @@ -24,5 +24,6 @@ LIBVIRT_ADMIN_1.3.0 { virAdmConnectUnregisterCloseCallback; virAdmConnectListServers; virAdmServerGetName; + virAdmServerGetThreadPoolParameters; virAdmServerFree; }; diff --git a/src/rpc/virnetserver.c b/src/rpc/virnetserver.c index 547e52e..cc809bf 100644 --- a/src/rpc/virnetserver.c +++ b/src/rpc/virnetserver.c @@ -861,3 +861,25 @@ virNetServerStart(virNetServerPtr srv) return virNetServerMDNSStart(srv->mdns); } + +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 89d8db9..f392c73 100644 --- a/src/rpc/virnetserver.h +++ b/src/rpc/virnetserver.h @@ -85,4 +85,17 @@ void virNetServerUpdateServices(virNetServerPtr srv, bool enabled); int virNetServerStart(virNetServerPtr srv); +int +virNetServerGetThreadPoolParameters(virNetServerPtr srv, + size_t *minWorkers, + size_t *maxWorkers, + size_t *nWorkers, + size_t *freeWorkers, + size_t *nPrioWorkers, + size_t *jobQueueDepth); + +int virNetServerSetThreadPoolParameters(virNetServerPtr srv, + long long int minWorkers, + long long int maxWorkers, + long long int prioWorkers); #endif /* __VIR_NET_SERVER_H__ */ -- 2.4.3 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list