[libvirt] [PATCH REPOST 0/5] admin: Introduce APIs to get/set client processing

This is just a rebased version of https://www.redhat.com/archives/libvir-list/2016-April/msg00466.html. Patches 1/7 and 2/7 of the original series were already pushed with another series. Erik Skultety (5): virnetserver: Introduce client processing controls getters admin: Introduce some public constants related to client processing controls admin: Introduce virAdmServerGetClientProcessingControls admin: Introduce virAdmServerSetClientProcessingControls virt-admin: Introduce commands srv-clients-info and srv-clients-set daemon/admin.c | 86 +++++++++++++++++++ daemon/admin_server.c | 76 +++++++++++++++++ daemon/admin_server.h | 10 +++ include/libvirt/libvirt-admin.h | 52 ++++++++++++ src/admin/admin_protocol.x | 30 ++++++- src/admin/admin_remote.c | 74 +++++++++++++++++ src/admin_protocol-structs | 20 +++++ src/libvirt-admin.c | 89 ++++++++++++++++++++ src/libvirt_admin_private.syms | 3 + src/libvirt_admin_public.syms | 2 + src/rpc/virnetserver.c | 83 +++++++++++++++++++ src/rpc/virnetserver.h | 9 ++ tools/virt-admin.c | 177 ++++++++++++++++++++++++++++++++++++++++ 13 files changed, 710 insertions(+), 1 deletion(-) -- 2.5.5

Add some trivial getters for client related attributes to virnetserver before any admin method can be introduced. Signed-off-by: Erik Skultety <eskultet@redhat.com> --- src/rpc/virnetserver.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ src/rpc/virnetserver.h | 5 +++++ 2 files changed, 54 insertions(+) diff --git a/src/rpc/virnetserver.c b/src/rpc/virnetserver.c index 60541cb..2cd1765 100644 --- a/src/rpc/virnetserver.c +++ b/src/rpc/virnetserver.c @@ -941,6 +941,55 @@ virNetServerSetThreadPoolParameters(virNetServerPtr srv, ret = virThreadPoolSetParameters(srv->workers, minWorkers, maxWorkers, prioWorkers); virObjectUnlock(srv); + + return ret; +} + +size_t +virNetServerGetMaxClients(virNetServerPtr srv) +{ + size_t ret; + + virObjectLock(srv); + ret = srv->nclients_max; + virObjectUnlock(srv); + + return ret; +} + +size_t +virNetServerGetCurrentClients(virNetServerPtr srv) +{ + size_t ret; + + virObjectLock(srv); + ret = srv->nclients; + virObjectUnlock(srv); + + return ret; +} + +size_t +virNetServerGetMaxUnauthClients(virNetServerPtr srv) +{ + size_t ret; + + virObjectLock(srv); + ret = srv->nclients_unauth_max; + virObjectUnlock(srv); + + return ret; +} + +size_t +virNetServerGetCurrentUnauthClients(virNetServerPtr srv) +{ + size_t ret; + + virObjectLock(srv); + ret = srv->nclients_unauth; + virObjectUnlock(srv); + return ret; } diff --git a/src/rpc/virnetserver.h b/src/rpc/virnetserver.h index 993bda7..a08cab0 100644 --- a/src/rpc/virnetserver.h +++ b/src/rpc/virnetserver.h @@ -111,4 +111,9 @@ virNetServerClientPtr virNetServerGetClient(virNetServerPtr srv, int virNetServerGetClients(virNetServerPtr srv, virNetServerClientPtr **clients); +size_t virNetServerGetMaxClients(virNetServerPtr srv); +size_t virNetServerGetCurrentClients(virNetServerPtr srv); +size_t virNetServerGetMaxUnauthClients(virNetServerPtr srv); +size_t virNetServerGetCurrentUnauthClients(virNetServerPtr srv); + #endif /* __VIR_NET_SERVER_H__ */ -- 2.5.5

On 11.05.2016 12:20, Erik Skultety wrote:
Add some trivial getters for client related attributes to virnetserver before any admin method can be introduced.
Signed-off-by: Erik Skultety <eskultet@redhat.com> --- src/rpc/virnetserver.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ src/rpc/virnetserver.h | 5 +++++ 2 files changed, 54 insertions(+)
diff --git a/src/rpc/virnetserver.h b/src/rpc/virnetserver.h index 993bda7..a08cab0 100644 --- a/src/rpc/virnetserver.h +++ b/src/rpc/virnetserver.h @@ -111,4 +111,9 @@ virNetServerClientPtr virNetServerGetClient(virNetServerPtr srv, int virNetServerGetClients(virNetServerPtr srv, virNetServerClientPtr **clients);
+size_t virNetServerGetMaxClients(virNetServerPtr srv); +size_t virNetServerGetCurrentClients(virNetServerPtr srv); +size_t virNetServerGetMaxUnauthClients(virNetServerPtr srv); +size_t virNetServerGetCurrentUnauthClients(virNetServerPtr srv); + #endif /* __VIR_NET_SERVER_H__ */
Don't forget to add these symbols to src/libvirt_remote.syms. Michal

In order for typed params validation to pass on daemon side, we should encourage users to use our exported constants with typed params to diminish to avoid any potential problems related to argument validity. Signed-off-by: Erik Skultety <eskultet@redhat.com> --- include/libvirt/libvirt-admin.h | 42 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/include/libvirt/libvirt-admin.h b/include/libvirt/libvirt-admin.h index 4e6074e..245313e 100644 --- a/include/libvirt/libvirt-admin.h +++ b/include/libvirt/libvirt-admin.h @@ -351,6 +351,48 @@ int virAdmClientGetInfo(virAdmClientPtr client, int virAdmClientClose(virAdmClientPtr client, unsigned int flags); +/* Manage per-server client processing controls */ + +/** + * VIR_SERVER_CLIENTS_MAX: + * Macro for per-server nclients_max limit: represents the upper limit to + * number of clients connected to the server, as uint. + */ + +# define VIR_SERVER_CLIENTS_MAX "nclients_max" + +/** + * VIR_SERVER_CLIENTS_CURRENT: + * Macro for per-server nclients attribute: represents the current number of + * clients connected to the server, as VIR_TYPED_PARAM_UINT. + * + * NOTE: This attribute is read-only and any attempt to set it will be denied + * by daemon + */ + +# define VIR_SERVER_CLIENTS_CURRENT "nclients" + +/** + * VIR_SERVER_CLIENTS_UNAUTH_MAX: + * Macro for per-server nclients_unauth_max limit: represents the upper limit + * to number of clients connected to the server, but not authenticated yet, + * as VIR_TYPED_PARAM_UINT. + */ + +# define VIR_SERVER_CLIENTS_UNAUTH_MAX "nclients_unauth_max" + +/** + * VIR_SERVER_CLIENTS_UNAUTH_CURRENT: + * Macro for per-server nclients_unauth attribute: represents the current + * number of clients connected to the server, but not authenticated yet, + * as VIR_TYPED_PARAM_UINT. + * + * NOTE: This attribute is read-only and any attempt to set it will be denied + * by daemon + */ + +# define VIR_SERVER_CLIENTS_UNAUTH_CURRENT "nclients_unauth" + # ifdef __cplusplus } # endif -- 2.5.5

On 11.05.2016 12:20, Erik Skultety wrote:
In order for typed params validation to pass on daemon side, we should encourage users to use our exported constants with typed params to diminish to avoid any potential problems related to argument validity.
Signed-off-by: Erik Skultety <eskultet@redhat.com> --- include/libvirt/libvirt-admin.h | 42 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+)
diff --git a/include/libvirt/libvirt-admin.h b/include/libvirt/libvirt-admin.h index 4e6074e..245313e 100644 --- a/include/libvirt/libvirt-admin.h +++ b/include/libvirt/libvirt-admin.h @@ -351,6 +351,48 @@ int virAdmClientGetInfo(virAdmClientPtr client,
int virAdmClientClose(virAdmClientPtr client, unsigned int flags);
+/* Manage per-server client processing controls */ + +/** + * VIR_SERVER_CLIENTS_MAX: + * Macro for per-server nclients_max limit: represents the upper limit to + * number of clients connected to the server, as uint. + */ + +# define VIR_SERVER_CLIENTS_MAX "nclients_max" + +/** + * VIR_SERVER_CLIENTS_CURRENT: + * Macro for per-server nclients attribute: represents the current number of + * clients connected to the server, as VIR_TYPED_PARAM_UINT. + * + * NOTE: This attribute is read-only and any attempt to set it will be denied + * by daemon + */ + +# define VIR_SERVER_CLIENTS_CURRENT "nclients" + +/** + * VIR_SERVER_CLIENTS_UNAUTH_MAX: + * Macro for per-server nclients_unauth_max limit: represents the upper limit + * to number of clients connected to the server, but not authenticated yet, + * as VIR_TYPED_PARAM_UINT. + */ + +# define VIR_SERVER_CLIENTS_UNAUTH_MAX "nclients_unauth_max" + +/** + * VIR_SERVER_CLIENTS_UNAUTH_CURRENT: + * Macro for per-server nclients_unauth attribute: represents the current + * number of clients connected to the server, but not authenticated yet, + * as VIR_TYPED_PARAM_UINT. + * + * NOTE: This attribute is read-only and any attempt to set it will be denied + * by daemon + */ + +# define VIR_SERVER_CLIENTS_UNAUTH_CURRENT "nclients_unauth" +
I wonder whether we should expose other two knobs max_queued_clients and max_client_requests. While those are currently not part of virNetServer rather than virNetServerService, there's no model of service now. The way we have it documented now suggests those are part of server.
# ifdef __cplusplus } # endif
Michal

On 11/05/16 14:35, Michal Privoznik wrote:
On 11.05.2016 12:20, Erik Skultety wrote:
In order for typed params validation to pass on daemon side, we should encourage users to use our exported constants with typed params to diminish to avoid any potential problems related to argument validity.
Signed-off-by: Erik Skultety <eskultet@redhat.com> --- include/libvirt/libvirt-admin.h | 42 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+)
diff --git a/include/libvirt/libvirt-admin.h b/include/libvirt/libvirt-admin.h index 4e6074e..245313e 100644 --- a/include/libvirt/libvirt-admin.h +++ b/include/libvirt/libvirt-admin.h @@ -351,6 +351,48 @@ int virAdmClientGetInfo(virAdmClientPtr client,
int virAdmClientClose(virAdmClientPtr client, unsigned int flags);
+/* Manage per-server client processing controls */ + +/** + * VIR_SERVER_CLIENTS_MAX: + * Macro for per-server nclients_max limit: represents the upper limit to + * number of clients connected to the server, as uint. + */ + +# define VIR_SERVER_CLIENTS_MAX "nclients_max" + +/** + * VIR_SERVER_CLIENTS_CURRENT: + * Macro for per-server nclients attribute: represents the current number of + * clients connected to the server, as VIR_TYPED_PARAM_UINT. + * + * NOTE: This attribute is read-only and any attempt to set it will be denied + * by daemon + */ + +# define VIR_SERVER_CLIENTS_CURRENT "nclients" + +/** + * VIR_SERVER_CLIENTS_UNAUTH_MAX: + * Macro for per-server nclients_unauth_max limit: represents the upper limit + * to number of clients connected to the server, but not authenticated yet, + * as VIR_TYPED_PARAM_UINT. + */ + +# define VIR_SERVER_CLIENTS_UNAUTH_MAX "nclients_unauth_max" + +/** + * VIR_SERVER_CLIENTS_UNAUTH_CURRENT: + * Macro for per-server nclients_unauth attribute: represents the current + * number of clients connected to the server, but not authenticated yet, + * as VIR_TYPED_PARAM_UINT. + * + * NOTE: This attribute is read-only and any attempt to set it will be denied + * by daemon + */ + +# define VIR_SERVER_CLIENTS_UNAUTH_CURRENT "nclients_unauth" +
I wonder whether we should expose other two knobs max_queued_clients and max_client_requests. While those are currently not part of virNetServer rather than virNetServerService, there's no model of service now. The way we have it documented now suggests those are part of server.
# ifdef __cplusplus } # endif
Michal
Well, I can also imagine a per-client setting regarding the maximum number of requests it can make. I think we can wait till there's need for that and enable both the per-client max number of requests and per-server max number of requests for all clients connected to that server. About the max number of queued clients, well, since this can only be set during startup when the socket is created and cannot be changed thereafter without destroying the socket and creating another one instead, I don't see much usage in polling for that attribute, since it's going to have the same value as the config says. Erik

Enable retrieval of the number of maximum clients connected to all sockets combined as well as the number of maximum clients waiting for authentication, in order to be successfully connected. These are the attributes configurable through libvirtd.conf, however, it could be handy to not only know values for these limits, but also the values for the current number of clients connected and number of clients currently waiting for authentication which are changing dynamically. This API does both, retrieves the limits as well as the current dynamic values. Signed-off-by: Erik Skultety <eskultet@redhat.com> --- daemon/admin.c | 45 +++++++++++++++++++++++++++++++++++++++++ daemon/admin_server.c | 41 +++++++++++++++++++++++++++++++++++++ daemon/admin_server.h | 5 +++++ include/libvirt/libvirt-admin.h | 5 +++++ src/admin/admin_protocol.x | 19 ++++++++++++++++- src/admin/admin_remote.c | 39 +++++++++++++++++++++++++++++++++++ src/admin_protocol-structs | 11 ++++++++++ src/libvirt-admin.c | 43 +++++++++++++++++++++++++++++++++++++++ src/libvirt_admin_private.syms | 2 ++ src/libvirt_admin_public.syms | 1 + 10 files changed, 210 insertions(+), 1 deletion(-) diff --git a/daemon/admin.c b/daemon/admin.c index 03774d7..819b1c0 100644 --- a/daemon/admin.c +++ b/daemon/admin.c @@ -301,4 +301,49 @@ adminDispatchClientGetInfo(virNetServerPtr server ATTRIBUTE_UNUSED, virObjectUnref(srv); return rv; } + +static int +adminDispatchServerGetClientProcessingControls(virNetServerPtr server ATTRIBUTE_UNUSED, + virNetServerClientPtr client, + virNetMessagePtr msg ATTRIBUTE_UNUSED, + virNetMessageErrorPtr rerr ATTRIBUTE_UNUSED, + admin_server_get_client_processing_controls_args *args, + admin_server_get_client_processing_controls_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 (adminServerGetClientProcessingControls(srv, ¶ms, &nparams, + args->flags) < 0) + goto cleanup; + + if (nparams > ADMIN_SERVER_CLIENT_PROCESSING_CONTROLS_MAX) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Number of client processing parameters %d exceeds " + "max allowed limit: %d"), nparams, + ADMIN_SERVER_CLIENT_PROCESSING_CONTROLS_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 9f40688..79437a1 100644 --- a/daemon/admin_server.c +++ b/daemon/admin_server.c @@ -311,3 +311,44 @@ int adminClientClose(virNetServerClientPtr client, virNetServerClientClose(client); return 0; } + +int +adminServerGetClientProcessingControls(virNetServerPtr srv, + virTypedParameterPtr *params, + int *nparams, + unsigned int flags) +{ + int ret = -1; + int maxparams = 0; + virTypedParameterPtr tmpparams = NULL; + + virCheckFlags(0, -1); + + if (virTypedParamsAddUInt(&tmpparams, nparams, &maxparams, + VIR_SERVER_CLIENTS_MAX, + virNetServerGetMaxClients(srv)) < 0) + goto cleanup; + + if (virTypedParamsAddUInt(&tmpparams, nparams, &maxparams, + VIR_SERVER_CLIENTS_CURRENT, + virNetServerGetCurrentClients(srv)) < 0) + goto cleanup; + + if (virTypedParamsAddUInt(&tmpparams, nparams, &maxparams, + VIR_SERVER_CLIENTS_UNAUTH_MAX, + virNetServerGetMaxUnauthClients(srv)) < 0) + goto cleanup; + + if (virTypedParamsAddUInt(&tmpparams, nparams, &maxparams, + VIR_SERVER_CLIENTS_UNAUTH_CURRENT, + virNetServerGetCurrentUnauthClients(srv)) < 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 2953e10..279e530 100644 --- a/daemon/admin_server.h +++ b/daemon/admin_server.h @@ -62,4 +62,9 @@ int adminClientGetInfo(virNetServerClientPtr client, int adminClientClose(virNetServerClientPtr client, unsigned int flags); +int adminServerGetClientProcessingControls(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 245313e..bb290e3 100644 --- a/include/libvirt/libvirt-admin.h +++ b/include/libvirt/libvirt-admin.h @@ -393,6 +393,11 @@ int virAdmClientClose(virAdmClientPtr client, unsigned int flags); # define VIR_SERVER_CLIENTS_UNAUTH_CURRENT "nclients_unauth" +int virAdmServerGetClientProcessingControls(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 1da7f90..249c062 100644 --- a/src/admin/admin_protocol.x +++ b/src/admin/admin_protocol.x @@ -45,6 +45,9 @@ const ADMIN_CLIENT_LIST_MAX = 16384; /* Upper limit on number of client info parameters */ const ADMIN_CLIENT_INFO_PARAMETERS_MAX = 64; +/* Upper limit on number of client processing controls */ +const ADMIN_SERVER_CLIENT_PROCESSING_CONTROLS_MAX = 32; + /* A long string, which may NOT be NULL. */ typedef string admin_nonnull_string<ADMIN_STRING_MAX>; @@ -165,6 +168,15 @@ struct admin_client_close_args { unsigned int flags; }; +struct admin_server_get_client_processing_controls_args { + admin_nonnull_server srv; + unsigned int flags; +}; + +struct admin_server_get_client_processing_controls_ret { + admin_typed_param params<ADMIN_SERVER_CLIENT_PROCESSING_CONTROLS_MAX>; +}; + /* Define the program number, protocol version and procedure numbers here. */ const ADMIN_PROGRAM = 0x06900690; const ADMIN_PROTOCOL_VERSION = 1; @@ -240,5 +252,10 @@ enum admin_procedure { /** * @generate: both */ - ADMIN_PROC_CLIENT_CLOSE = 11 + ADMIN_PROC_CLIENT_CLOSE = 11, + + /** + * @generate: none + */ + ADMIN_PROC_SERVER_GET_CLIENT_PROCESSING_CONTROLS = 12 }; diff --git a/src/admin/admin_remote.c b/src/admin/admin_remote.c index 632aaa8..e3fae4b 100644 --- a/src/admin/admin_remote.c +++ b/src/admin/admin_remote.c @@ -355,3 +355,42 @@ remoteAdminClientGetInfo(virAdmClientPtr client, virObjectUnlock(priv); return rv; } + +static int +remoteAdminServerGetClientProcessingControls(virAdmServerPtr srv, + virTypedParameterPtr *params, + int *nparams, + unsigned int flags) +{ + int rv = -1; + admin_server_get_client_processing_controls_args args; + admin_server_get_client_processing_controls_ret ret; + remoteAdminPrivPtr priv = srv->conn->privateData; + 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_CLIENT_PROCESSING_CONTROLS, + (xdrproc_t) xdr_admin_server_get_client_processing_controls_args, + (char *) &args, + (xdrproc_t) xdr_admin_server_get_client_processing_controls_ret, + (char *) &ret) == -1) + goto cleanup; + + if (virTypedParamsDeserialize((virTypedParameterRemotePtr) ret.params.params_val, + ret.params.params_len, + ADMIN_SERVER_CLIENT_PROCESSING_CONTROLS_MAX, + params, + nparams) < 0) + goto cleanup; + + rv = 0; + xdr_free((xdrproc_t) xdr_admin_server_get_client_processing_controls_ret, + (char *) &ret); + + cleanup: + virObjectUnlock(priv); + return rv; +} diff --git a/src/admin_protocol-structs b/src/admin_protocol-structs index b4db415..3ea0ba6 100644 --- a/src/admin_protocol-structs +++ b/src/admin_protocol-structs @@ -109,6 +109,16 @@ struct admin_client_close_args { admin_nonnull_client clnt; u_int flags; }; +struct admin_server_get_client_processing_controls_args { + admin_nonnull_server srv; + u_int flags; +}; +struct admin_server_get_client_processing_controls_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, @@ -121,4 +131,5 @@ enum admin_procedure { ADMIN_PROC_SERVER_LOOKUP_CLIENT = 9, ADMIN_PROC_CLIENT_GET_INFO = 10, ADMIN_PROC_CLIENT_CLOSE = 11, + ADMIN_PROC_SERVER_GET_CLIENT_PROCESSING_CONTROLS = 12, }; diff --git a/src/libvirt-admin.c b/src/libvirt-admin.c index 9d5e5b9..0b317c5 100644 --- a/src/libvirt-admin.c +++ b/src/libvirt-admin.c @@ -1000,3 +1000,46 @@ int virAdmClientClose(virAdmClientPtr client, virDispatchError(NULL); return -1; } + +/** + * virAdmServerGetClientProcessingControls: + * @srv: a valid server object reference + * @params: pointer to client processing controls object + * (return value, allocated automatically) + * @nparams: pointer to number of parameters returned in @params + * @flags: extra flags; not used yet, so callers should always pass 0 + * + * Retrieve client processing controls. These include: + * - current number of clients connected to @srv, + * - maximum number of clients connected to @srv, + * - current number of clients connected to @srv waiting for authentication, + * - maximum number of clients connected to @srv that can be wainting for + * authentication. + * + * Returns 0 on success, allocating @params to size returned in @nparams, or + * -1 in case of an error. Caller is responsible for deallocating @params. + */ +int +virAdmServerGetClientProcessingControls(virAdmServerPtr srv, + virTypedParameterPtr *params, + int *nparams, + unsigned int flags) +{ + int ret = -1; + + VIR_DEBUG("srv=%p, flags=%x", srv, flags); + virResetLastError(); + + virCheckAdmServerGoto(srv, error); + virCheckFlagsGoto(0, error); + + if ((ret = remoteAdminServerGetClientProcessingControls(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 e55b91e..9a30ff5 100644 --- a/src/libvirt_admin_private.syms +++ b/src/libvirt_admin_private.syms @@ -15,6 +15,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_client_processing_controls_args; +xdr_admin_server_get_client_processing_controls_ret; xdr_admin_server_get_threadpool_parameters_args; xdr_admin_server_get_threadpool_parameters_ret; xdr_admin_server_list_clients_args; diff --git a/src/libvirt_admin_public.syms b/src/libvirt_admin_public.syms index 57df1f4..59b0160 100644 --- a/src/libvirt_admin_public.syms +++ b/src/libvirt_admin_public.syms @@ -35,4 +35,5 @@ LIBVIRT_ADMIN_1.3.0 { virAdmServerListClients; virAdmClientGetInfo; virAdmClientClose; + virAdmServerGetClientProcessingControls; }; -- 2.5.5

On 11.05.2016 12:20, Erik Skultety wrote:
Enable retrieval of the number of maximum clients connected to all sockets combined as well as the number of maximum clients waiting for authentication, in order to be successfully connected. These are the attributes configurable through libvirtd.conf, however, it could be handy to not only know values for these limits, but also the values for the current number of clients connected and number of clients currently waiting for authentication which are changing dynamically. This API does both, retrieves the limits as well as the current dynamic values.
Signed-off-by: Erik Skultety <eskultet@redhat.com> --- daemon/admin.c | 45 +++++++++++++++++++++++++++++++++++++++++ daemon/admin_server.c | 41 +++++++++++++++++++++++++++++++++++++ daemon/admin_server.h | 5 +++++ include/libvirt/libvirt-admin.h | 5 +++++ src/admin/admin_protocol.x | 19 ++++++++++++++++- src/admin/admin_remote.c | 39 +++++++++++++++++++++++++++++++++++ src/admin_protocol-structs | 11 ++++++++++ src/libvirt-admin.c | 43 +++++++++++++++++++++++++++++++++++++++ src/libvirt_admin_private.syms | 2 ++ src/libvirt_admin_public.syms | 1 + 10 files changed, 210 insertions(+), 1 deletion(-)
diff --git a/daemon/admin.c b/daemon/admin.c index 03774d7..819b1c0 100644 --- a/daemon/admin.c +++ b/daemon/admin.c @@ -301,4 +301,49 @@ adminDispatchClientGetInfo(virNetServerPtr server ATTRIBUTE_UNUSED, virObjectUnref(srv); return rv; } + +static int +adminDispatchServerGetClientProcessingControls(virNetServerPtr server ATTRIBUTE_UNUSED,
Ugrh. I couldn't say it in one breath. How about virAdminServerGetClientLimits? Yeah, not much shorter.
+ virNetServerClientPtr client, + virNetMessagePtr msg ATTRIBUTE_UNUSED, + virNetMessageErrorPtr rerr ATTRIBUTE_UNUSED, + admin_server_get_client_processing_controls_args *args, + admin_server_get_client_processing_controls_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 (adminServerGetClientProcessingControls(srv, ¶ms, &nparams, + args->flags) < 0) + goto cleanup; + + if (nparams > ADMIN_SERVER_CLIENT_PROCESSING_CONTROLS_MAX) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Number of client processing parameters %d exceeds " + "max allowed limit: %d"), nparams, + ADMIN_SERVER_CLIENT_PROCESSING_CONTROLS_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 9f40688..79437a1 100644 --- a/daemon/admin_server.c +++ b/daemon/admin_server.c @@ -311,3 +311,44 @@ int adminClientClose(virNetServerClientPtr client, virNetServerClientClose(client); return 0; } + +int +adminServerGetClientProcessingControls(virNetServerPtr srv, + virTypedParameterPtr *params, + int *nparams, + unsigned int flags) +{ + int ret = -1; + int maxparams = 0; + virTypedParameterPtr tmpparams = NULL; + + virCheckFlags(0, -1); + + if (virTypedParamsAddUInt(&tmpparams, nparams, &maxparams, + VIR_SERVER_CLIENTS_MAX, + virNetServerGetMaxClients(srv)) < 0) + goto cleanup; + + if (virTypedParamsAddUInt(&tmpparams, nparams, &maxparams, + VIR_SERVER_CLIENTS_CURRENT, + virNetServerGetCurrentClients(srv)) < 0) + goto cleanup; + + if (virTypedParamsAddUInt(&tmpparams, nparams, &maxparams, + VIR_SERVER_CLIENTS_UNAUTH_MAX, + virNetServerGetMaxUnauthClients(srv)) < 0) + goto cleanup; + + if (virTypedParamsAddUInt(&tmpparams, nparams, &maxparams, + VIR_SERVER_CLIENTS_UNAUTH_CURRENT, + virNetServerGetCurrentUnauthClients(srv)) < 0) + goto cleanup;
Well, all of these are type of size_t in our implementation. Should we make these ULL?
+ + *params = tmpparams; + tmpparams = NULL; + ret = 0; + + cleanup: + virTypedParamsFree(tmpparams, *nparams); + return ret; +}
diff --git a/src/libvirt-admin.c b/src/libvirt-admin.c index 9d5e5b9..0b317c5 100644 --- a/src/libvirt-admin.c +++ b/src/libvirt-admin.c @@ -1000,3 +1000,46 @@ int virAdmClientClose(virAdmClientPtr client, virDispatchError(NULL); return -1; } + +/** + * virAdmServerGetClientProcessingControls: + * @srv: a valid server object reference + * @params: pointer to client processing controls object + * (return value, allocated automatically) + * @nparams: pointer to number of parameters returned in @params + * @flags: extra flags; not used yet, so callers should always pass 0 + * + * Retrieve client processing controls. These include: + * - current number of clients connected to @srv, + * - maximum number of clients connected to @srv, + * - current number of clients connected to @srv waiting for authentication, + * - maximum number of clients connected to @srv that can be wainting for + * authentication. + * + * Returns 0 on success, allocating @params to size returned in @nparams, or + * -1 in case of an error. Caller is responsible for deallocating @params. + */ +int +virAdmServerGetClientProcessingControls(virAdmServerPtr srv, + virTypedParameterPtr *params, + int *nparams, + unsigned int flags) +{ + int ret = -1; + + VIR_DEBUG("srv=%p, flags=%x", srv, flags); + virResetLastError(); + + virCheckAdmServerGoto(srv, error); + virCheckFlagsGoto(0, error);
Drop this check ^^
+ + if ((ret = remoteAdminServerGetClientProcessingControls(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 e55b91e..9a30ff5 100644 --- a/src/libvirt_admin_private.syms +++ b/src/libvirt_admin_private.syms @@ -15,6 +15,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_client_processing_controls_args; +xdr_admin_server_get_client_processing_controls_ret; xdr_admin_server_get_threadpool_parameters_args; xdr_admin_server_get_threadpool_parameters_ret; xdr_admin_server_list_clients_args; diff --git a/src/libvirt_admin_public.syms b/src/libvirt_admin_public.syms index 57df1f4..59b0160 100644 --- a/src/libvirt_admin_public.syms +++ b/src/libvirt_admin_public.syms @@ -35,4 +35,5 @@ LIBVIRT_ADMIN_1.3.0 { virAdmServerListClients; virAdmClientGetInfo; virAdmClientClose; + virAdmServerGetClientProcessingControls; };
Michal

diff --git a/daemon/admin_server.c b/daemon/admin_server.c index 9f40688..79437a1 100644 --- a/daemon/admin_server.c +++ b/daemon/admin_server.c @@ -311,3 +311,44 @@ int adminClientClose(virNetServerClientPtr client, virNetServerClientClose(client); return 0; } + +int +adminServerGetClientProcessingControls(virNetServerPtr srv, + virTypedParameterPtr *params, + int *nparams, + unsigned int flags) +{ + int ret = -1; + int maxparams = 0; + virTypedParameterPtr tmpparams = NULL; + + virCheckFlags(0, -1); + + if (virTypedParamsAddUInt(&tmpparams, nparams, &maxparams, + VIR_SERVER_CLIENTS_MAX, + virNetServerGetMaxClients(srv)) < 0) + goto cleanup; + + if (virTypedParamsAddUInt(&tmpparams, nparams, &maxparams, + VIR_SERVER_CLIENTS_CURRENT, + virNetServerGetCurrentClients(srv)) < 0) + goto cleanup; + + if (virTypedParamsAddUInt(&tmpparams, nparams, &maxparams, + VIR_SERVER_CLIENTS_UNAUTH_MAX, + virNetServerGetMaxUnauthClients(srv)) < 0) + goto cleanup; + + if (virTypedParamsAddUInt(&tmpparams, nparams, &maxparams, + VIR_SERVER_CLIENTS_UNAUTH_CURRENT, + virNetServerGetCurrentUnauthClients(srv)) < 0) + goto cleanup;
Well, all of these are type of size_t in our implementation. Should we make these ULL?
I don't think that's necessary. In my understanding, this is strongly affected by the max number of allowed file descriptors per process, and since 'fd' is int, ULL would be a slight overkill and think UINT will suffice. I will of course fix your other notes to this patch/ Erik

On 11.05.2016 15:39, Erik Skultety wrote:
diff --git a/daemon/admin_server.c b/daemon/admin_server.c index 9f40688..79437a1 100644 --- a/daemon/admin_server.c +++ b/daemon/admin_server.c @@ -311,3 +311,44 @@ int adminClientClose(virNetServerClientPtr client, virNetServerClientClose(client); return 0; } + +int +adminServerGetClientProcessingControls(virNetServerPtr srv, + virTypedParameterPtr *params, + int *nparams, + unsigned int flags) +{ + int ret = -1; + int maxparams = 0; + virTypedParameterPtr tmpparams = NULL; + + virCheckFlags(0, -1); + + if (virTypedParamsAddUInt(&tmpparams, nparams, &maxparams, + VIR_SERVER_CLIENTS_MAX, + virNetServerGetMaxClients(srv)) < 0) + goto cleanup; + + if (virTypedParamsAddUInt(&tmpparams, nparams, &maxparams, + VIR_SERVER_CLIENTS_CURRENT, + virNetServerGetCurrentClients(srv)) < 0) + goto cleanup; + + if (virTypedParamsAddUInt(&tmpparams, nparams, &maxparams, + VIR_SERVER_CLIENTS_UNAUTH_MAX, + virNetServerGetMaxUnauthClients(srv)) < 0) + goto cleanup; + + if (virTypedParamsAddUInt(&tmpparams, nparams, &maxparams, + VIR_SERVER_CLIENTS_UNAUTH_CURRENT, + virNetServerGetCurrentUnauthClients(srv)) < 0) + goto cleanup;
Well, all of these are type of size_t in our implementation. Should we make these ULL?
I don't think that's necessary. In my understanding, this is strongly affected by the max number of allowed file descriptors per process, and since 'fd' is int, ULL would be a slight overkill and think UINT will suffice.
I will of course fix your other notes to this patch/
Erik
Okay. I think you have covered all my concerns then. ACK series. Michal

Opposite operation to virAdmServerGetClientProcessingControls. Understandably though, setting values for current number of clients connected or still waiting for authentication does not make sense, since changes to these values are event dependent, i.e. a client connects - counter is increased. Thus only the limits to maximum clients connected and waiting for authentication can be set. Should a request for other controls to be set arrive (provided such a setting will be first introduced to the config), the set of configuration controls can be later expanded (thanks to typed params). This patch also introduces a constraint that the maximum number of clients waiting for authentication has to be less than the overall maximum number of clients connected and any attempt to violate this constraint will be denied. Signed-off-by: Erik Skultety <eskultet@redhat.com> --- daemon/admin.c | 41 ++++++++++++++++++++++++++++++++++++ daemon/admin_server.c | 35 +++++++++++++++++++++++++++++++ daemon/admin_server.h | 5 +++++ include/libvirt/libvirt-admin.h | 5 +++++ src/admin/admin_protocol.x | 13 +++++++++++- src/admin/admin_remote.c | 35 +++++++++++++++++++++++++++++++ src/admin_protocol-structs | 9 ++++++++ src/libvirt-admin.c | 46 +++++++++++++++++++++++++++++++++++++++++ src/libvirt_admin_private.syms | 1 + src/libvirt_admin_public.syms | 1 + src/rpc/virnetserver.c | 34 ++++++++++++++++++++++++++++++ src/rpc/virnetserver.h | 4 ++++ 12 files changed, 228 insertions(+), 1 deletion(-) diff --git a/daemon/admin.c b/daemon/admin.c index 819b1c0..8cdcaed 100644 --- a/daemon/admin.c +++ b/daemon/admin.c @@ -346,4 +346,45 @@ adminDispatchServerGetClientProcessingControls(virNetServerPtr server ATTRIBUTE_ virObjectUnref(srv); return rv; } + +static int +adminDispatchServerSetClientProcessingControls(virNetServerPtr server ATTRIBUTE_UNUSED, + virNetServerClientPtr client, + virNetMessagePtr msg ATTRIBUTE_UNUSED, + virNetMessageErrorPtr rerr ATTRIBUTE_UNUSED, + admin_server_set_client_processing_controls_args *args) +{ + 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))) { + virReportError(VIR_ERR_NO_SERVER, + _("no server with matching name '%s' found"), + args->srv.name); + goto cleanup; + } + + if (virTypedParamsDeserialize((virTypedParameterRemotePtr) args->params.params_val, + args->params.params_len, + ADMIN_SERVER_CLIENT_PROCESSING_CONTROLS_MAX, + ¶ms, + &nparams) < 0) + goto cleanup; + + if (adminServerSetClientProcessingControls(srv, params, nparams, + args->flags) < 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 79437a1..65c35a7 100644 --- a/daemon/admin_server.c +++ b/daemon/admin_server.c @@ -352,3 +352,38 @@ adminServerGetClientProcessingControls(virNetServerPtr srv, virTypedParamsFree(tmpparams, *nparams); return ret; } + +int +adminServerSetClientProcessingControls(virNetServerPtr srv, + virTypedParameterPtr params, + int nparams, + unsigned int flags) +{ + long long int maxClients = -1; + long long int maxClientsUnauth = -1; + virTypedParameterPtr param = NULL; + + virCheckFlags(0, -1); + + if (virTypedParamsValidate(params, nparams, + VIR_SERVER_CLIENTS_MAX, + VIR_TYPED_PARAM_UINT, + VIR_SERVER_CLIENTS_UNAUTH_MAX, + VIR_TYPED_PARAM_UINT, + NULL) < 0) + return -1; + + if ((param = virTypedParamsGet(params, nparams, + VIR_SERVER_CLIENTS_MAX))) + maxClients = param->value.ui; + + if ((param = virTypedParamsGet(params, nparams, + VIR_SERVER_CLIENTS_UNAUTH_MAX))) + maxClientsUnauth = param->value.ui; + + if (virNetServerSetClientProcessingControls(srv, maxClients, + maxClientsUnauth) < 0) + return -1; + + return 0; +} diff --git a/daemon/admin_server.h b/daemon/admin_server.h index 279e530..dff3a20 100644 --- a/daemon/admin_server.h +++ b/daemon/admin_server.h @@ -67,4 +67,9 @@ int adminServerGetClientProcessingControls(virNetServerPtr srv, int *nparams, unsigned int flags); +int adminServerSetClientProcessingControls(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 bb290e3..860d074 100644 --- a/include/libvirt/libvirt-admin.h +++ b/include/libvirt/libvirt-admin.h @@ -398,6 +398,11 @@ int virAdmServerGetClientProcessingControls(virAdmServerPtr srv, int *nparams, unsigned int flags); +int virAdmServerSetClientProcessingControls(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 249c062..26aa625 100644 --- a/src/admin/admin_protocol.x +++ b/src/admin/admin_protocol.x @@ -177,6 +177,12 @@ struct admin_server_get_client_processing_controls_ret { admin_typed_param params<ADMIN_SERVER_CLIENT_PROCESSING_CONTROLS_MAX>; }; +struct admin_server_set_client_processing_controls_args { + admin_nonnull_server srv; + admin_typed_param params<ADMIN_SERVER_CLIENT_PROCESSING_CONTROLS_MAX>; + unsigned int flags; +}; + /* Define the program number, protocol version and procedure numbers here. */ const ADMIN_PROGRAM = 0x06900690; const ADMIN_PROTOCOL_VERSION = 1; @@ -257,5 +263,10 @@ enum admin_procedure { /** * @generate: none */ - ADMIN_PROC_SERVER_GET_CLIENT_PROCESSING_CONTROLS = 12 + ADMIN_PROC_SERVER_GET_CLIENT_PROCESSING_CONTROLS = 12, + + /** + * @generate: none + */ + ADMIN_PROC_SERVER_SET_CLIENT_PROCESSING_CONTROLS = 13 }; diff --git a/src/admin/admin_remote.c b/src/admin/admin_remote.c index e3fae4b..a948ee9 100644 --- a/src/admin/admin_remote.c +++ b/src/admin/admin_remote.c @@ -394,3 +394,38 @@ remoteAdminServerGetClientProcessingControls(virAdmServerPtr srv, virObjectUnlock(priv); return rv; } + +static int +remoteAdminServerSetClientProcessingControls(virAdmServerPtr srv, + virTypedParameterPtr params, + int nparams, + unsigned int flags) +{ + int rv = -1; + admin_server_set_client_processing_controls_args args; + remoteAdminPrivPtr priv = srv->conn->privateData; + + args.flags = flags; + make_nonnull_server(&args.srv, srv); + + virObjectLock(priv); + + if (virTypedParamsSerialize(params, nparams, + (virTypedParameterRemotePtr *) &args.params.params_val, + &args.params.params_len, + 0) < 0) + goto cleanup; + + if (call(srv->conn, 0, ADMIN_PROC_SERVER_SET_CLIENT_PROCESSING_CONTROLS, + (xdrproc_t) xdr_admin_server_set_client_processing_controls_args, + (char *) &args, + (xdrproc_t) xdr_void, (char *) NULL) == -1) + goto cleanup; + + rv = 0; + cleanup: + virTypedParamsRemoteFree((virTypedParameterRemotePtr) args.params.params_val, + args.params.params_len); + virObjectUnlock(priv); + return rv; +} diff --git a/src/admin_protocol-structs b/src/admin_protocol-structs index 3ea0ba6..d09d671 100644 --- a/src/admin_protocol-structs +++ b/src/admin_protocol-structs @@ -119,6 +119,14 @@ struct admin_server_get_client_processing_controls_ret { admin_typed_param * params_val; } params; }; +struct admin_server_set_client_processing_controls_args { + admin_nonnull_server srv; + struct { + u_int params_len; + admin_typed_param * params_val; + } params; + u_int flags; +}; enum admin_procedure { ADMIN_PROC_CONNECT_OPEN = 1, ADMIN_PROC_CONNECT_CLOSE = 2, @@ -132,4 +140,5 @@ enum admin_procedure { ADMIN_PROC_CLIENT_GET_INFO = 10, ADMIN_PROC_CLIENT_CLOSE = 11, ADMIN_PROC_SERVER_GET_CLIENT_PROCESSING_CONTROLS = 12, + ADMIN_PROC_SERVER_SET_CLIENT_PROCESSING_CONTROLS = 13, }; diff --git a/src/libvirt-admin.c b/src/libvirt-admin.c index 0b317c5..302212f 100644 --- a/src/libvirt-admin.c +++ b/src/libvirt-admin.c @@ -1043,3 +1043,49 @@ virAdmServerGetClientProcessingControls(virAdmServerPtr srv, virDispatchError(NULL); return -1; } + +/** + * virAdmServerSetClientProcessingControls: + * @srv: a valid server object reference + * @params: pointer to client processing controls object + * @nparams: number of parameters in @params + * @flags: extra flags; not used yet, so callers should always pass 0 + * + * Change client processing controls configuration on server @srv. + * + * Caller is responsible for allocating @params prior to calling this function. + * See 'Manage per-server client processing controls' in libvirt-admin.h for + * supported parameters in @params. + * + * Returns 0 if the controls have been changed successfully or -1 in case of an + * error. + */ +int +virAdmServerSetClientProcessingControls(virAdmServerPtr srv, + virTypedParameterPtr params, + int nparams, + unsigned int flags) +{ + int ret = -1; + + VIR_DEBUG("srv=%p, params=%p, nparams=%d, flags=%x", srv, params, nparams, + flags); + VIR_TYPED_PARAMS_DEBUG(params, nparams); + + virResetLastError(); + + virCheckAdmServerGoto(srv, error); + virCheckNonNullArgGoto(params, error); + virCheckPositiveArgGoto(nparams, error); + virCheckFlagsGoto(0, error); + + if ((ret = remoteAdminServerSetClientProcessingControls(srv, params, + nparams, + flags)) < 0) + goto error; + + return ret; + error: + virDispatchError(NULL); + return ret; +} diff --git a/src/libvirt_admin_private.syms b/src/libvirt_admin_private.syms index 9a30ff5..d0da0d6 100644 --- a/src/libvirt_admin_private.syms +++ b/src/libvirt_admin_private.syms @@ -23,6 +23,7 @@ xdr_admin_server_list_clients_args; xdr_admin_server_list_clients_ret; xdr_admin_server_lookup_client_args; xdr_admin_server_lookup_client_ret; +xdr_admin_server_set_client_processing_controls_args; xdr_admin_server_set_threadpool_parameters_args; # datatypes.h diff --git a/src/libvirt_admin_public.syms b/src/libvirt_admin_public.syms index 59b0160..411dd2c 100644 --- a/src/libvirt_admin_public.syms +++ b/src/libvirt_admin_public.syms @@ -36,4 +36,5 @@ LIBVIRT_ADMIN_1.3.0 { virAdmClientGetInfo; virAdmClientClose; virAdmServerGetClientProcessingControls; + virAdmServerSetClientProcessingControls; }; diff --git a/src/rpc/virnetserver.c b/src/rpc/virnetserver.c index 2cd1765..4c4b144 100644 --- a/src/rpc/virnetserver.c +++ b/src/rpc/virnetserver.c @@ -1044,3 +1044,37 @@ virNetServerGetClient(virNetServerPtr srv, _("No client with matching ID '%llu'"), id); return ret; } + +int +virNetServerSetClientProcessingControls(virNetServerPtr srv, + long long int maxClients, + long long int maxClientsUnauth) +{ + int ret = -1; + size_t max, max_unauth; + + virObjectLock(srv); + + max = maxClients >= 0 ? maxClients : srv->nclients_max; + max_unauth = maxClientsUnauth >= 0 ? + maxClientsUnauth : srv->nclients_unauth_max; + + if (max < max_unauth) { + virReportError(VIR_ERR_INVALID_ARG, "%s", + _("The overall maximum number of clients must be " + "greater than the maximum number of clients waiting " + "for authentication")); + goto cleanup; + } + + if (maxClients >= 0) + srv->nclients_max = maxClients; + + if (maxClientsUnauth >= 0) + srv->nclients_unauth_max = maxClientsUnauth; + + ret = 0; + cleanup: + virObjectUnlock(srv); + return ret; +} diff --git a/src/rpc/virnetserver.h b/src/rpc/virnetserver.h index a08cab0..38107b4 100644 --- a/src/rpc/virnetserver.h +++ b/src/rpc/virnetserver.h @@ -116,4 +116,8 @@ size_t virNetServerGetCurrentClients(virNetServerPtr srv); size_t virNetServerGetMaxUnauthClients(virNetServerPtr srv); size_t virNetServerGetCurrentUnauthClients(virNetServerPtr srv); +int virNetServerSetClientProcessingControls(virNetServerPtr srv, + long long int maxClients, + long long int maxClientsUnauth); + #endif /* __VIR_NET_SERVER_H__ */ -- 2.5.5

On 11.05.2016 12:20, Erik Skultety wrote:
Opposite operation to virAdmServerGetClientProcessingControls. Understandably though, setting values for current number of clients connected or still waiting for authentication does not make sense, since changes to these values are event dependent, i.e. a client connects - counter is increased. Thus only the limits to maximum clients connected and waiting for authentication can be set. Should a request for other controls to be set arrive (provided such a setting will be first introduced to the config), the set of configuration controls can be later expanded (thanks to typed params). This patch also introduces a constraint that the maximum number of clients waiting for authentication has to be less than the overall maximum number of clients connected and any attempt to violate this constraint will be denied.
Signed-off-by: Erik Skultety <eskultet@redhat.com> --- daemon/admin.c | 41 ++++++++++++++++++++++++++++++++++++ daemon/admin_server.c | 35 +++++++++++++++++++++++++++++++ daemon/admin_server.h | 5 +++++ include/libvirt/libvirt-admin.h | 5 +++++ src/admin/admin_protocol.x | 13 +++++++++++- src/admin/admin_remote.c | 35 +++++++++++++++++++++++++++++++ src/admin_protocol-structs | 9 ++++++++ src/libvirt-admin.c | 46 +++++++++++++++++++++++++++++++++++++++++ src/libvirt_admin_private.syms | 1 + src/libvirt_admin_public.syms | 1 + src/rpc/virnetserver.c | 34 ++++++++++++++++++++++++++++++ src/rpc/virnetserver.h | 4 ++++ 12 files changed, 228 insertions(+), 1 deletion(-)
diff --git a/daemon/admin.c b/daemon/admin.c index 819b1c0..8cdcaed 100644 --- a/daemon/admin.c +++ b/daemon/admin.c @@ -346,4 +346,45 @@ adminDispatchServerGetClientProcessingControls(virNetServerPtr server ATTRIBUTE_ virObjectUnref(srv); return rv; } + +static int +adminDispatchServerSetClientProcessingControls(virNetServerPtr server ATTRIBUTE_UNUSED, + virNetServerClientPtr client, + virNetMessagePtr msg ATTRIBUTE_UNUSED, + virNetMessageErrorPtr rerr ATTRIBUTE_UNUSED, + admin_server_set_client_processing_controls_args *args)
Yet again, if we decide to change the name in previous patch, this one should be changed as well.
+{ + 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))) { + virReportError(VIR_ERR_NO_SERVER, + _("no server with matching name '%s' found"), + args->srv.name); + goto cleanup; + } + + if (virTypedParamsDeserialize((virTypedParameterRemotePtr) args->params.params_val, + args->params.params_len, + ADMIN_SERVER_CLIENT_PROCESSING_CONTROLS_MAX, + ¶ms, + &nparams) < 0) + goto cleanup; + + if (adminServerSetClientProcessingControls(srv, params, nparams, + args->flags) < 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 79437a1..65c35a7 100644 --- a/daemon/admin_server.c +++ b/daemon/admin_server.c @@ -352,3 +352,38 @@ adminServerGetClientProcessingControls(virNetServerPtr srv, virTypedParamsFree(tmpparams, *nparams); return ret; } + +int +adminServerSetClientProcessingControls(virNetServerPtr srv, + virTypedParameterPtr params, + int nparams, + unsigned int flags) +{ + long long int maxClients = -1; + long long int maxClientsUnauth = -1; + virTypedParameterPtr param = NULL; + + virCheckFlags(0, -1); + + if (virTypedParamsValidate(params, nparams, + VIR_SERVER_CLIENTS_MAX, + VIR_TYPED_PARAM_UINT, + VIR_SERVER_CLIENTS_UNAUTH_MAX, + VIR_TYPED_PARAM_UINT, + NULL) < 0) + return -1;
Same comment here as in the previous patch. Should we accept ULL value instead of UINT? Or am I just bikeshedding...
+ + if ((param = virTypedParamsGet(params, nparams, + VIR_SERVER_CLIENTS_MAX))) + maxClients = param->value.ui; + + if ((param = virTypedParamsGet(params, nparams, + VIR_SERVER_CLIENTS_UNAUTH_MAX))) + maxClientsUnauth = param->value.ui; + + if (virNetServerSetClientProcessingControls(srv, maxClients, + maxClientsUnauth) < 0) + return -1; + + return 0; +}
diff --git a/src/libvirt-admin.c b/src/libvirt-admin.c index 0b317c5..302212f 100644 --- a/src/libvirt-admin.c +++ b/src/libvirt-admin.c @@ -1043,3 +1043,49 @@ virAdmServerGetClientProcessingControls(virAdmServerPtr srv, virDispatchError(NULL); return -1; } + +/** + * virAdmServerSetClientProcessingControls: + * @srv: a valid server object reference + * @params: pointer to client processing controls object + * @nparams: number of parameters in @params + * @flags: extra flags; not used yet, so callers should always pass 0 + * + * Change client processing controls configuration on server @srv. + * + * Caller is responsible for allocating @params prior to calling this function. + * See 'Manage per-server client processing controls' in libvirt-admin.h for + * supported parameters in @params. + * + * Returns 0 if the controls have been changed successfully or -1 in case of an + * error. + */ +int +virAdmServerSetClientProcessingControls(virAdmServerPtr srv, + virTypedParameterPtr params, + int nparams, + unsigned int flags) +{ + int ret = -1; + + VIR_DEBUG("srv=%p, params=%p, nparams=%d, flags=%x", srv, params, nparams, + flags); + VIR_TYPED_PARAMS_DEBUG(params, nparams); + + virResetLastError(); + + virCheckAdmServerGoto(srv, error); + virCheckNonNullArgGoto(params, error); + virCheckPositiveArgGoto(nparams, error); + virCheckFlagsGoto(0, error);
Yet again, drop this check.
+ + if ((ret = remoteAdminServerSetClientProcessingControls(srv, params, + nparams, + flags)) < 0) + goto error; + + return ret; + error: + virDispatchError(NULL); + return ret; +} diff --git a/src/libvirt_admin_private.syms b/src/libvirt_admin_private.syms index 9a30ff5..d0da0d6 100644 --- a/src/libvirt_admin_private.syms +++ b/src/libvirt_admin_private.syms @@ -23,6 +23,7 @@ xdr_admin_server_list_clients_args; xdr_admin_server_list_clients_ret; xdr_admin_server_lookup_client_args; xdr_admin_server_lookup_client_ret; +xdr_admin_server_set_client_processing_controls_args; xdr_admin_server_set_threadpool_parameters_args;
# datatypes.h diff --git a/src/libvirt_admin_public.syms b/src/libvirt_admin_public.syms index 59b0160..411dd2c 100644 --- a/src/libvirt_admin_public.syms +++ b/src/libvirt_admin_public.syms @@ -36,4 +36,5 @@ LIBVIRT_ADMIN_1.3.0 { virAdmClientGetInfo; virAdmClientClose; virAdmServerGetClientProcessingControls; + virAdmServerSetClientProcessingControls; }; diff --git a/src/rpc/virnetserver.c b/src/rpc/virnetserver.c index 2cd1765..4c4b144 100644 --- a/src/rpc/virnetserver.c +++ b/src/rpc/virnetserver.c @@ -1044,3 +1044,37 @@ virNetServerGetClient(virNetServerPtr srv, _("No client with matching ID '%llu'"), id); return ret; } + +int +virNetServerSetClientProcessingControls(virNetServerPtr srv, + long long int maxClients, + long long int maxClientsUnauth) +{ + int ret = -1; + size_t max, max_unauth; + + virObjectLock(srv); + + max = maxClients >= 0 ? maxClients : srv->nclients_max; + max_unauth = maxClientsUnauth >= 0 ? + maxClientsUnauth : srv->nclients_unauth_max; + + if (max < max_unauth) { + virReportError(VIR_ERR_INVALID_ARG, "%s", + _("The overall maximum number of clients must be " + "greater than the maximum number of clients waiting " + "for authentication")); + goto cleanup; + }
Whoa, we don't have this check when creating new server. I guess we should do that.
+ + if (maxClients >= 0) + srv->nclients_max = maxClients; + + if (maxClientsUnauth >= 0) + srv->nclients_unauth_max = maxClientsUnauth; + + ret = 0; + cleanup: + virObjectUnlock(srv); + return ret; +} diff --git a/src/rpc/virnetserver.h b/src/rpc/virnetserver.h index a08cab0..38107b4 100644 --- a/src/rpc/virnetserver.h +++ b/src/rpc/virnetserver.h @@ -116,4 +116,8 @@ size_t virNetServerGetCurrentClients(virNetServerPtr srv); size_t virNetServerGetMaxUnauthClients(virNetServerPtr srv); size_t virNetServerGetCurrentUnauthClients(virNetServerPtr srv);
+int virNetServerSetClientProcessingControls(virNetServerPtr srv, + long long int maxClients, + long long int maxClientsUnauth); + #endif /* __VIR_NET_SERVER_H__ */
Michal

diff --git a/src/rpc/virnetserver.c b/src/rpc/virnetserver.c index 2cd1765..4c4b144 100644 --- a/src/rpc/virnetserver.c +++ b/src/rpc/virnetserver.c @@ -1044,3 +1044,37 @@ virNetServerGetClient(virNetServerPtr srv, _("No client with matching ID '%llu'"), id); return ret; } + +int +virNetServerSetClientProcessingControls(virNetServerPtr srv, + long long int maxClients, + long long int maxClientsUnauth) +{ + int ret = -1; + size_t max, max_unauth; + + virObjectLock(srv); + + max = maxClients >= 0 ? maxClients : srv->nclients_max; + max_unauth = maxClientsUnauth >= 0 ? + maxClientsUnauth : srv->nclients_unauth_max; + + if (max < max_unauth) { + virReportError(VIR_ERR_INVALID_ARG, "%s", + _("The overall maximum number of clients must be " + "greater than the maximum number of clients waiting " + "for authentication")); + goto cleanup; + }
Whoa, we don't have this check when creating new server. I guess we should do that.
Well, you might be right, but then, let's say someone who has a configuration with max_unauth > max updates to upstream and the daemon just refuses to start because it is now considered invalid. I know that we can't change the logic in a way that would make existing VMs disappear, but what about daemon refusing to start because the original configuration that used to work is now considered invalid? Should we error out or just warn and modify the attributes, so that the '>' constraint is met? For now, I adjusted the patches according to your notes, except for this one and sent v2. I would like to hear your opinion on this one, it's no problem to make some final adjustment to the patch before it will be merged. Erik

Finally wire-up the client processing controls APIs into virt-admin client. Signed-off-by: Erik Skultety <eskultet@redhat.com> --- tools/virt-admin.c | 177 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 177 insertions(+) diff --git a/tools/virt-admin.c b/tools/virt-admin.c index 90ad765..ee14fd4 100644 --- a/tools/virt-admin.c +++ b/tools/virt-admin.c @@ -809,6 +809,171 @@ cmdClientDisconnect(vshControl *ctl, const vshCmd *cmd) return ret; } +/* ------------------- + * Command srv-clients-info + * ------------------------ + */ + +static const vshCmdInfo info_srv_clients_info[] = { + {.name = "help", + .data = N_("get server's client processing controls configuration") + }, + {.name = "desc", + .data = N_("Retrieve server's client processing controls configuration.") + }, + {.name = NULL} +}; + +static const vshCmdOptDef opts_srv_clients_info[] = { + {.name = "server", + .type = VSH_OT_DATA, + .flags = VSH_OFLAG_REQ, + .help = N_("Server to retrieve client processing controls from."), + }, + {.name = NULL} +}; + +static bool +cmdSrvClientsInfo(vshControl *ctl, const vshCmd *cmd) +{ + bool ret = false; + virTypedParameterPtr params = NULL; + int nparams = 0; + size_t i; + const char *srvname = NULL; + virAdmServerPtr srv = NULL; + vshAdmControlPtr priv = ctl->privData; + + if (vshCommandOptStringReq(ctl, cmd, "server", &srvname) < 0) + return false; + + if (!(srv = virAdmConnectLookupServer(priv->conn, srvname, 0))) + goto cleanup; + + if (virAdmServerGetClientProcessingControls(srv, ¶ms, + &nparams, 0) < 0) { + vshError(ctl, "%s", _("Unable to retrieve client processing controls " + "from server's configuration")); + goto cleanup; + } + + for (i = 0; i < nparams; i++) + vshPrint(ctl, "%-15s: %d\n", params[i].field, params[i].value.ui); + + ret = true; + + cleanup: + virTypedParamsFree(params, nparams); + if (srv) + virAdmServerFree(srv); + return ret; +} + +/* ----------------------- + * Command srv-clients-set + * ----------------------- + */ + +static const vshCmdInfo info_srv_clients_set[] = { + {.name = "help", + .data = N_("set server's client processing controls configuration") + }, + {.name = "desc", + .data = N_("Tune server's client processing controls configuration. " + "See OPTIONS for currently supported attributes.") + }, + {.name = NULL} +}; + +static const vshCmdOptDef opts_srv_clients_set[] = { + {.name = "server", + .type = VSH_OT_DATA, + .flags = VSH_OFLAG_REQ, + .help = N_("Server to alter the client processing controls on."), + }, + {.name = "max-clients", + .type = VSH_OT_INT, + .help = N_("Change the upper limit to overall number of clients " + "connected to the server."), + }, + {.name = "max-unauth-clients", + .type = VSH_OT_INT, + .help = N_("Change the upper limit to number of clients waiting for " + "authentication to be connected to the server"), + }, + {.name = NULL} +}; + +static bool +cmdSrvClientsSet(vshControl *ctl, const vshCmd *cmd) +{ + bool ret = false; + int rv = 0; + unsigned int val, max, unauth_max; + int maxparams = 0; + int nparams = 0; + const char *srvname = NULL; + virAdmServerPtr srv = NULL; + virTypedParameterPtr params = NULL; + vshAdmControlPtr priv = ctl->privData; + + if (vshCommandOptStringReq(ctl, cmd, "server", &srvname) < 0) + return false; + +#define PARSE_CMD_TYPED_PARAM(NAME, FIELD) \ + if ((rv = vshCommandOptUInt(ctl, cmd, NAME, &val)) < 0) { \ + vshError(ctl, _("Unable to parse integer parameter '%s'"), NAME); \ + goto cleanup; \ + } else if (rv > 0) { \ + if (virTypedParamsAddUInt(¶ms, &nparams, &maxparams, \ + FIELD, val) < 0) \ + goto save_error; \ + } + + PARSE_CMD_TYPED_PARAM("max-clients", VIR_SERVER_CLIENTS_MAX); + PARSE_CMD_TYPED_PARAM("max-unauth-clients", VIR_SERVER_CLIENTS_UNAUTH_MAX); + +#undef PARSE_CMD_TYPED_PARAM + + if (!nparams) { + vshError(ctl, "%s", _("At least one of options --max-clients, " + "--max-unauth-clients is mandatory")); + goto cleanup; + } + + if (virTypedParamsGetUInt(params, nparams, + VIR_SERVER_CLIENTS_MAX, &max) && + virTypedParamsGetUInt(params, nparams, + VIR_SERVER_CLIENTS_UNAUTH_MAX, &unauth_max) && + unauth_max > max) { + vshError(ctl, "%s", _("--max-unauth-clients must be less than " + "--max-clients")); + goto cleanup; + } + + if (!(srv = virAdmConnectLookupServer(priv->conn, srvname, 0))) + goto cleanup; + + if (virAdmServerSetClientProcessingControls(srv, params, nparams, 0) < 0) + goto error; + + ret = true; + + cleanup: + virTypedParamsFree(params, nparams); + if (srv) + virAdmServerFree(srv); + return ret; + + save_error: + vshSaveLibvirtError(); + + error: + vshError(ctl, "%s", _("Unable to change server's client processing " + "controls configuration")); + goto cleanup; +} + static void * vshAdmConnectionHandler(vshControl *ctl) { @@ -1126,6 +1291,12 @@ static const vshCmdDef monitoringCmds[] = { .info = info_client_info, .flags = 0 }, + {.name = "srv-clients-info", + .handler = cmdSrvClientsInfo, + .opts = opts_srv_clients_info, + .info = info_srv_clients_info, + .flags = 0 + }, {.name = NULL} }; @@ -1142,6 +1313,12 @@ static const vshCmdDef managementCmds[] = { .info = info_client_disconnect, .flags = 0 }, + {.name = "srv-clients-set", + .handler = cmdSrvClientsSet, + .opts = opts_srv_clients_set, + .info = info_srv_clients_set, + .flags = 0 + }, {.name = NULL} }; -- 2.5.5

On 11.05.2016 12:20, Erik Skultety wrote:
Finally wire-up the client processing controls APIs into virt-admin client.
Signed-off-by: Erik Skultety <eskultet@redhat.com> --- tools/virt-admin.c | 177 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 177 insertions(+)
D'oh! you forgot the man page update.
diff --git a/tools/virt-admin.c b/tools/virt-admin.c index 90ad765..ee14fd4 100644 --- a/tools/virt-admin.c +++ b/tools/virt-admin.c @@ -809,6 +809,171 @@ cmdClientDisconnect(vshControl *ctl, const vshCmd *cmd) return ret; }
+/* ------------------- + * Command srv-clients-info + * ------------------------ + */ + +static const vshCmdInfo info_srv_clients_info[] = { + {.name = "help", + .data = N_("get server's client processing controls configuration") + }, + {.name = "desc", + .data = N_("Retrieve server's client processing controls configuration.") + }, + {.name = NULL} +}; + +static const vshCmdOptDef opts_srv_clients_info[] = { + {.name = "server", + .type = VSH_OT_DATA, + .flags = VSH_OFLAG_REQ, + .help = N_("Server to retrieve client processing controls from."), + }, + {.name = NULL} +}; + +static bool +cmdSrvClientsInfo(vshControl *ctl, const vshCmd *cmd) +{ + bool ret = false; + virTypedParameterPtr params = NULL; + int nparams = 0; + size_t i; + const char *srvname = NULL; + virAdmServerPtr srv = NULL; + vshAdmControlPtr priv = ctl->privData; + + if (vshCommandOptStringReq(ctl, cmd, "server", &srvname) < 0) + return false; + + if (!(srv = virAdmConnectLookupServer(priv->conn, srvname, 0))) + goto cleanup; + + if (virAdmServerGetClientProcessingControls(srv, ¶ms, + &nparams, 0) < 0) { + vshError(ctl, "%s", _("Unable to retrieve client processing controls " + "from server's configuration")); + goto cleanup; + } + + for (i = 0; i < nparams; i++) + vshPrint(ctl, "%-15s: %d\n", params[i].field, params[i].value.ui); + + ret = true; + + cleanup: + virTypedParamsFree(params, nparams); + if (srv) + virAdmServerFree(srv);
There's no need for this check. Fortunately this is a wise free API of ours as it accepts NULL.
+ return ret; +} + +/* ----------------------- + * Command srv-clients-set + * ----------------------- + */ + +static const vshCmdInfo info_srv_clients_set[] = { + {.name = "help", + .data = N_("set server's client processing controls configuration") + }, + {.name = "desc", + .data = N_("Tune server's client processing controls configuration. " + "See OPTIONS for currently supported attributes.") + }, + {.name = NULL} +}; + +static const vshCmdOptDef opts_srv_clients_set[] = { + {.name = "server", + .type = VSH_OT_DATA, + .flags = VSH_OFLAG_REQ, + .help = N_("Server to alter the client processing controls on."), + }, + {.name = "max-clients", + .type = VSH_OT_INT, + .help = N_("Change the upper limit to overall number of clients " + "connected to the server."), + }, + {.name = "max-unauth-clients", + .type = VSH_OT_INT, + .help = N_("Change the upper limit to number of clients waiting for " + "authentication to be connected to the server"), + }, + {.name = NULL} +}; + +static bool +cmdSrvClientsSet(vshControl *ctl, const vshCmd *cmd) +{ + bool ret = false; + int rv = 0; + unsigned int val, max, unauth_max; + int maxparams = 0; + int nparams = 0; + const char *srvname = NULL; + virAdmServerPtr srv = NULL; + virTypedParameterPtr params = NULL; + vshAdmControlPtr priv = ctl->privData; + + if (vshCommandOptStringReq(ctl, cmd, "server", &srvname) < 0) + return false; + +#define PARSE_CMD_TYPED_PARAM(NAME, FIELD) \ + if ((rv = vshCommandOptUInt(ctl, cmd, NAME, &val)) < 0) { \ + vshError(ctl, _("Unable to parse integer parameter '%s'"), NAME); \ + goto cleanup; \ + } else if (rv > 0) { \ + if (virTypedParamsAddUInt(¶ms, &nparams, &maxparams, \ + FIELD, val) < 0) \ + goto save_error; \ + } + + PARSE_CMD_TYPED_PARAM("max-clients", VIR_SERVER_CLIENTS_MAX); + PARSE_CMD_TYPED_PARAM("max-unauth-clients", VIR_SERVER_CLIENTS_UNAUTH_MAX); + +#undef PARSE_CMD_TYPED_PARAM + + if (!nparams) { + vshError(ctl, "%s", _("At least one of options --max-clients, " + "--max-unauth-clients is mandatory")); + goto cleanup; + } + + if (virTypedParamsGetUInt(params, nparams, + VIR_SERVER_CLIENTS_MAX, &max) && + virTypedParamsGetUInt(params, nparams, + VIR_SERVER_CLIENTS_UNAUTH_MAX, &unauth_max) && + unauth_max > max) { + vshError(ctl, "%s", _("--max-unauth-clients must be less than " + "--max-clients")); + goto cleanup; + } + + if (!(srv = virAdmConnectLookupServer(priv->conn, srvname, 0))) + goto cleanup; + + if (virAdmServerSetClientProcessingControls(srv, params, nparams, 0) < 0) + goto error; + + ret = true; + + cleanup: + virTypedParamsFree(params, nparams); + if (srv) + virAdmServerFree(srv);
Same here.
+ return ret; + + save_error: + vshSaveLibvirtError(); + + error: + vshError(ctl, "%s", _("Unable to change server's client processing " + "controls configuration")); + goto cleanup; +} + static void * vshAdmConnectionHandler(vshControl *ctl) { @@ -1126,6 +1291,12 @@ static const vshCmdDef monitoringCmds[] = { .info = info_client_info, .flags = 0 }, + {.name = "srv-clients-info", + .handler = cmdSrvClientsInfo, + .opts = opts_srv_clients_info, + .info = info_srv_clients_info, + .flags = 0 + }, {.name = NULL} };
@@ -1142,6 +1313,12 @@ static const vshCmdDef managementCmds[] = { .info = info_client_disconnect, .flags = 0 }, + {.name = "srv-clients-set", + .handler = cmdSrvClientsSet, + .opts = opts_srv_clients_set, + .info = info_srv_clients_set, + .flags = 0 + }, {.name = NULL} };
Michal

On 11.05.2016 12:20, Erik Skultety wrote:
This is just a rebased version of https://www.redhat.com/archives/libvir-list/2016-April/msg00466.html. Patches 1/7 and 2/7 of the original series were already pushed with another series.
Erik Skultety (5): virnetserver: Introduce client processing controls getters admin: Introduce some public constants related to client processing controls admin: Introduce virAdmServerGetClientProcessingControls admin: Introduce virAdmServerSetClientProcessingControls virt-admin: Introduce commands srv-clients-info and srv-clients-set
daemon/admin.c | 86 +++++++++++++++++++ daemon/admin_server.c | 76 +++++++++++++++++ daemon/admin_server.h | 10 +++ include/libvirt/libvirt-admin.h | 52 ++++++++++++ src/admin/admin_protocol.x | 30 ++++++- src/admin/admin_remote.c | 74 +++++++++++++++++ src/admin_protocol-structs | 20 +++++ src/libvirt-admin.c | 89 ++++++++++++++++++++ src/libvirt_admin_private.syms | 3 + src/libvirt_admin_public.syms | 2 + src/rpc/virnetserver.c | 83 +++++++++++++++++++ src/rpc/virnetserver.h | 9 ++ tools/virt-admin.c | 177 ++++++++++++++++++++++++++++++++++++++++ 13 files changed, 710 insertions(+), 1 deletion(-)
In general, I like this approach. And I'm very tempted to ACK it. But I'd rather have some discussion on the naming in patches 3 and 4. If we can come up with something better, you have my ACK. Michal
participants (2)
-
Erik Skultety
-
Michal Privoznik