[libvirt] [PATCH 0/7] Introduce APIs to get/set client processing controls

- APIs enable retrieval of values for maximum number of clients allowed to be connected, maximum number of clients allowed to wait for authentication, as well as current (dynamic) values for both cases; expectedly, setter only allows to set the limits available through libvirtd.conf - until patch "makefile: Move include/Makefile.am to include/libvirt/Makefile.am" is reviewed an pushed, config.status must be run after after 1/7 for a successful build. Erik Skultety (7): libvirt-host: Move virTypedParam* to libvirt-common admin: Enable usage of typed parameters 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 cfg.mk | 2 +- daemon/admin.c | 85 ++++++++++++++++ daemon/admin_server.c | 77 +++++++++++++++ daemon/admin_server.h | 10 ++ include/libvirt/libvirt-admin.h | 52 ++++++++++ include/libvirt/libvirt-common.h.in | 185 +++++++++++++++++++++++++++++++++++ include/libvirt/libvirt-host.h | 186 ------------------------------------ src/admin/admin_protocol.x | 54 ++++++++++- src/admin/admin_remote.c | 81 ++++++++++++++++ src/admin_protocol-structs | 45 +++++++++ src/libvirt-admin.c | 89 +++++++++++++++++ src/libvirt_admin_private.syms | 3 + src/libvirt_admin_public.syms | 2 + src/rpc/virnetserver.c | 82 ++++++++++++++++ src/rpc/virnetserver.h | 9 ++ tools/virt-admin.c | 182 +++++++++++++++++++++++++++++++++++ 16 files changed, 956 insertions(+), 188 deletions(-) -- 2.4.11

Commits 0472cef6, 9afc115f, 8cd1d546 exported typed params handlers internally, but a commit which would move the public definition from libvirt-host to libvirt-common was missing. Signed-off-by: Erik Skultety <eskultet@redhat.com> --- include/libvirt/libvirt-common.h.in | 185 +++++++++++++++++++++++++++++++++++ include/libvirt/libvirt-host.h | 186 ------------------------------------ 2 files changed, 185 insertions(+), 186 deletions(-) diff --git a/include/libvirt/libvirt-common.h.in b/include/libvirt/libvirt-common.h.in index efbb91b..772e40f 100644 --- a/include/libvirt/libvirt-common.h.in +++ b/include/libvirt/libvirt-common.h.in @@ -120,6 +120,191 @@ typedef enum { # endif } virConnectCloseReason; +/** + * virTypedParameterType: + * + * Express the type of a virTypedParameter + */ +typedef enum { + VIR_TYPED_PARAM_INT = 1, /* integer case */ + VIR_TYPED_PARAM_UINT = 2, /* unsigned integer case */ + VIR_TYPED_PARAM_LLONG = 3, /* long long case */ + VIR_TYPED_PARAM_ULLONG = 4, /* unsigned long long case */ + VIR_TYPED_PARAM_DOUBLE = 5, /* double case */ + VIR_TYPED_PARAM_BOOLEAN = 6, /* boolean(character) case */ + VIR_TYPED_PARAM_STRING = 7, /* string case */ + +# ifdef VIR_ENUM_SENTINELS + VIR_TYPED_PARAM_LAST +# endif +} virTypedParameterType; + +/** + * virTypedParameterFlags: + * + * Flags related to libvirt APIs that use virTypedParameter. + * + * These enums should not conflict with those of virDomainModificationImpact. + */ +typedef enum { + /* 1 << 0 is reserved for virDomainModificationImpact */ + /* 1 << 1 is reserved for virDomainModificationImpact */ + + /* Older servers lacked the ability to handle string typed + * parameters. Attempts to set a string parameter with an older + * server will fail at the client, but attempts to retrieve + * parameters must not return strings from a new server to an + * older client, so this flag exists to identify newer clients to + * newer servers. This flag is automatically set when needed, so + * the user does not have to worry about it; however, manually + * setting the flag can be used to reject servers that cannot + * return typed strings, even if no strings would be returned. + */ + VIR_TYPED_PARAM_STRING_OKAY = 1 << 2, + +} virTypedParameterFlags; + +/** + * VIR_TYPED_PARAM_FIELD_LENGTH: + * + * Macro providing the field length of virTypedParameter name + */ +# define VIR_TYPED_PARAM_FIELD_LENGTH 80 + +/** + * virTypedParameter: + * + * A named parameter, including a type and value. + * + * The types virSchedParameter, virBlkioParameter, and + * virMemoryParameter are aliases of this type, for use when + * targeting libvirt earlier than 0.9.2. + */ +typedef struct _virTypedParameter virTypedParameter; + +struct _virTypedParameter { + char field[VIR_TYPED_PARAM_FIELD_LENGTH]; /* parameter name */ + int type; /* parameter type, virTypedParameterType */ + union { + int i; /* type is INT */ + unsigned int ui; /* type is UINT */ + long long int l; /* type is LLONG */ + unsigned long long int ul; /* type is ULLONG */ + double d; /* type is DOUBLE */ + char b; /* type is BOOLEAN */ + char *s; /* type is STRING, may not be NULL */ + } value; /* parameter value */ +}; + +/** + * virTypedParameterPtr: + * + * a pointer to a virTypedParameter structure. + */ +typedef virTypedParameter *virTypedParameterPtr; + + +virTypedParameterPtr +virTypedParamsGet (virTypedParameterPtr params, + int nparams, + const char *name); +int +virTypedParamsGetInt (virTypedParameterPtr params, + int nparams, + const char *name, + int *value); +int +virTypedParamsGetUInt (virTypedParameterPtr params, + int nparams, + const char *name, + unsigned int *value); +int +virTypedParamsGetLLong (virTypedParameterPtr params, + int nparams, + const char *name, + long long *value); +int +virTypedParamsGetULLong (virTypedParameterPtr params, + int nparams, + const char *name, + unsigned long long *value); +int +virTypedParamsGetDouble (virTypedParameterPtr params, + int nparams, + const char *name, + double *value); +int +virTypedParamsGetBoolean(virTypedParameterPtr params, + int nparams, + const char *name, + int *value); +int +virTypedParamsGetString (virTypedParameterPtr params, + int nparams, + const char *name, + const char **value); +int +virTypedParamsAddInt (virTypedParameterPtr *params, + int *nparams, + int *maxparams, + const char *name, + int value); +int +virTypedParamsAddUInt (virTypedParameterPtr *params, + int *nparams, + int *maxparams, + const char *name, + unsigned int value); +int +virTypedParamsAddLLong (virTypedParameterPtr *params, + int *nparams, + int *maxparams, + const char *name, + long long value); +int +virTypedParamsAddULLong (virTypedParameterPtr *params, + int *nparams, + int *maxparams, + const char *name, + unsigned long long value); +int +virTypedParamsAddDouble (virTypedParameterPtr *params, + int *nparams, + int *maxparams, + const char *name, + double value); +int +virTypedParamsAddBoolean(virTypedParameterPtr *params, + int *nparams, + int *maxparams, + const char *name, + int value); +int +virTypedParamsAddString (virTypedParameterPtr *params, + int *nparams, + int *maxparams, + const char *name, + const char *value); +int +virTypedParamsAddStringList(virTypedParameterPtr *params, + int *nparams, + int *maxparams, + const char *name, + const char **values); +int +virTypedParamsAddFromString(virTypedParameterPtr *params, + int *nparams, + int *maxparams, + const char *name, + int type, + const char *value); +void +virTypedParamsClear (virTypedParameterPtr params, + int nparams); +void +virTypedParamsFree (virTypedParameterPtr params, + int nparams); + # ifdef __cplusplus } # endif diff --git a/include/libvirt/libvirt-host.h b/include/libvirt/libvirt-host.h index 8786fbb..07b5d15 100644 --- a/include/libvirt/libvirt-host.h +++ b/include/libvirt/libvirt-host.h @@ -140,192 +140,6 @@ struct _virSecurityModel { */ typedef virSecurityModel *virSecurityModelPtr; -/* Common data types shared among interfaces with name/type/value lists. */ - -/** - * virTypedParameterType: - * - * Express the type of a virTypedParameter - */ -typedef enum { - VIR_TYPED_PARAM_INT = 1, /* integer case */ - VIR_TYPED_PARAM_UINT = 2, /* unsigned integer case */ - VIR_TYPED_PARAM_LLONG = 3, /* long long case */ - VIR_TYPED_PARAM_ULLONG = 4, /* unsigned long long case */ - VIR_TYPED_PARAM_DOUBLE = 5, /* double case */ - VIR_TYPED_PARAM_BOOLEAN = 6, /* boolean(character) case */ - VIR_TYPED_PARAM_STRING = 7, /* string case */ - -# ifdef VIR_ENUM_SENTINELS - VIR_TYPED_PARAM_LAST -# endif -} virTypedParameterType; - -/** - * virTypedParameterFlags: - * - * Flags related to libvirt APIs that use virTypedParameter. - * - * These enums should not conflict with those of virDomainModificationImpact. - */ -typedef enum { - /* 1 << 0 is reserved for virDomainModificationImpact */ - /* 1 << 1 is reserved for virDomainModificationImpact */ - - /* Older servers lacked the ability to handle string typed - * parameters. Attempts to set a string parameter with an older - * server will fail at the client, but attempts to retrieve - * parameters must not return strings from a new server to an - * older client, so this flag exists to identify newer clients to - * newer servers. This flag is automatically set when needed, so - * the user does not have to worry about it; however, manually - * setting the flag can be used to reject servers that cannot - * return typed strings, even if no strings would be returned. - */ - VIR_TYPED_PARAM_STRING_OKAY = 1 << 2, - -} virTypedParameterFlags; - -/** - * VIR_TYPED_PARAM_FIELD_LENGTH: - * - * Macro providing the field length of virTypedParameter name - */ -# define VIR_TYPED_PARAM_FIELD_LENGTH 80 - -/** - * virTypedParameter: - * - * A named parameter, including a type and value. - * - * The types virSchedParameter, virBlkioParameter, and - * virMemoryParameter are aliases of this type, for use when - * targeting libvirt earlier than 0.9.2. - */ -typedef struct _virTypedParameter virTypedParameter; - -struct _virTypedParameter { - char field[VIR_TYPED_PARAM_FIELD_LENGTH]; /* parameter name */ - int type; /* parameter type, virTypedParameterType */ - union { - int i; /* type is INT */ - unsigned int ui; /* type is UINT */ - long long int l; /* type is LLONG */ - unsigned long long int ul; /* type is ULLONG */ - double d; /* type is DOUBLE */ - char b; /* type is BOOLEAN */ - char *s; /* type is STRING, may not be NULL */ - } value; /* parameter value */ -}; - -/** - * virTypedParameterPtr: - * - * a pointer to a virTypedParameter structure. - */ -typedef virTypedParameter *virTypedParameterPtr; - - -virTypedParameterPtr -virTypedParamsGet (virTypedParameterPtr params, - int nparams, - const char *name); -int -virTypedParamsGetInt (virTypedParameterPtr params, - int nparams, - const char *name, - int *value); -int -virTypedParamsGetUInt (virTypedParameterPtr params, - int nparams, - const char *name, - unsigned int *value); -int -virTypedParamsGetLLong (virTypedParameterPtr params, - int nparams, - const char *name, - long long *value); -int -virTypedParamsGetULLong (virTypedParameterPtr params, - int nparams, - const char *name, - unsigned long long *value); -int -virTypedParamsGetDouble (virTypedParameterPtr params, - int nparams, - const char *name, - double *value); -int -virTypedParamsGetBoolean(virTypedParameterPtr params, - int nparams, - const char *name, - int *value); -int -virTypedParamsGetString (virTypedParameterPtr params, - int nparams, - const char *name, - const char **value); -int -virTypedParamsAddInt (virTypedParameterPtr *params, - int *nparams, - int *maxparams, - const char *name, - int value); -int -virTypedParamsAddUInt (virTypedParameterPtr *params, - int *nparams, - int *maxparams, - const char *name, - unsigned int value); -int -virTypedParamsAddLLong (virTypedParameterPtr *params, - int *nparams, - int *maxparams, - const char *name, - long long value); -int -virTypedParamsAddULLong (virTypedParameterPtr *params, - int *nparams, - int *maxparams, - const char *name, - unsigned long long value); -int -virTypedParamsAddDouble (virTypedParameterPtr *params, - int *nparams, - int *maxparams, - const char *name, - double value); -int -virTypedParamsAddBoolean(virTypedParameterPtr *params, - int *nparams, - int *maxparams, - const char *name, - int value); -int -virTypedParamsAddString (virTypedParameterPtr *params, - int *nparams, - int *maxparams, - const char *name, - const char *value); -int -virTypedParamsAddStringList(virTypedParameterPtr *params, - int *nparams, - int *maxparams, - const char *name, - const char **values); -int -virTypedParamsAddFromString(virTypedParameterPtr *params, - int *nparams, - int *maxparams, - const char *name, - int type, - const char *value); -void -virTypedParamsClear (virTypedParameterPtr params, - int nparams); -void -virTypedParamsFree (virTypedParameterPtr params, - int nparams); /* data types related to virNodePtr */ -- 2.4.11

Make all relevant changes to admin interface and admin protocol, in order to support typed parameters within admin API as well. Signed-off-by: Erik Skultety <eskultet@redhat.com> --- cfg.mk | 2 +- daemon/admin.c | 1 + daemon/admin_server.c | 1 + src/admin/admin_protocol.x | 24 ++++++++++++++++++++++++ src/admin/admin_remote.c | 1 + src/admin_protocol-structs | 25 +++++++++++++++++++++++++ 6 files changed, 53 insertions(+), 1 deletion(-) diff --git a/cfg.mk b/cfg.mk index 8e8586f..61397e8 100644 --- a/cfg.mk +++ b/cfg.mk @@ -1227,7 +1227,7 @@ exclude_file_name_regexp--sc_prohibit_include_public_headers_brackets = \ ^(tools/|examples/|include/libvirt/(virterror|libvirt(-(admin|qemu|lxc))?)\.h$$) exclude_file_name_regexp--sc_prohibit_int_ijk = \ - ^(src/remote_protocol-structs|src/remote/remote_protocol.x|cfg.mk|include/)$ + ^(src/remote_protocol-structs|src/remote/remote_protocol.x|cfg.mk|include/|src/admin_protocol-structs|src/admin/admin_protocol.x)$ exclude_file_name_regexp--sc_prohibit_getenv = \ ^tests/.*\.[ch]$$ diff --git a/daemon/admin.c b/daemon/admin.c index 3169cdd..18ac22b 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 diff --git a/daemon/admin_server.c b/daemon/admin_server.c index 1d30ea5..e2ed1fe 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 "virtypedparam.h" #define VIR_FROM_THIS VIR_FROM_ADMIN diff --git a/src/admin/admin_protocol.x b/src/admin/admin_protocol.x index 6590980..57dbb6b 100644 --- a/src/admin/admin_protocol.x +++ b/src/admin/admin_protocol.x @@ -22,6 +22,7 @@ * Author: Martin Kletzander <mkletzan@redhat.com> */ +%#include <libvirt/libvirt-admin.h> %#include "virxdrdefs.h" /*----- Data types. -----*/ @@ -41,12 +42,35 @@ typedef string admin_nonnull_string<ADMIN_STRING_MAX>; /* A long string, which may be NULL. */ typedef admin_nonnull_string *admin_string; +union admin_typed_param_value switch (int type) { + case VIR_TYPED_PARAM_INT: + int i; + case VIR_TYPED_PARAM_UINT: + unsigned int ui; + case VIR_TYPED_PARAM_LLONG: + hyper l; + case VIR_TYPED_PARAM_ULLONG: + unsigned hyper ul; + case VIR_TYPED_PARAM_DOUBLE: + double d; + case VIR_TYPED_PARAM_BOOLEAN: + int b; + case VIR_TYPED_PARAM_STRING: + admin_nonnull_string s; +}; + +struct admin_typed_param { + admin_nonnull_string field; + admin_typed_param_value value; +}; + /* A server which may NOT be NULL */ struct admin_nonnull_server { admin_nonnull_string name; }; /*----- Protocol. -----*/ + struct admin_connect_open_args { unsigned int flags; }; diff --git a/src/admin/admin_remote.c b/src/admin/admin_remote.c index 21e0dd3..a1b2f84 100644 --- a/src/admin/admin_remote.c +++ b/src/admin/admin_remote.c @@ -23,6 +23,7 @@ #include <config.h> #include <rpc/rpc.h> #include "admin_protocol.h" +#include "virtypedparam.h" typedef struct _remoteAdminPriv remoteAdminPriv; typedef remoteAdminPriv *remoteAdminPrivPtr; diff --git a/src/admin_protocol-structs b/src/admin_protocol-structs index d8aca06..26c8443 100644 --- a/src/admin_protocol-structs +++ b/src/admin_protocol-structs @@ -1,4 +1,29 @@ /* -*- c -*- */ +enum { + VIR_TYPED_PARAM_INT = 1, + VIR_TYPED_PARAM_UINT = 2, + VIR_TYPED_PARAM_LLONG = 3, + VIR_TYPED_PARAM_ULLONG = 4, + VIR_TYPED_PARAM_DOUBLE = 5, + VIR_TYPED_PARAM_BOOLEAN = 6, + VIR_TYPED_PARAM_STRING = 7, +}; +struct admin_typed_param_value { + int type; + union { + int i; + u_int ui; + int64_t l; + uint64_t ul; + double d; + int b; + admin_nonnull_string s; + } admin_typed_param_value_u; +}; +struct admin_typed_param { + admin_nonnull_string field; + admin_typed_param_value value; +}; struct admin_nonnull_server { admin_nonnull_string name; }; -- 2.4.11

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 | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ src/rpc/virnetserver.h | 5 +++++ 2 files changed, 53 insertions(+) diff --git a/src/rpc/virnetserver.c b/src/rpc/virnetserver.c index cf48e50..38d807f 100644 --- a/src/rpc/virnetserver.c +++ b/src/rpc/virnetserver.c @@ -877,3 +877,51 @@ virNetServerGetName(virNetServerPtr srv) { return srv->name; } + +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 aa24440..770288d 100644 --- a/src/rpc/virnetserver.h +++ b/src/rpc/virnetserver.h @@ -89,4 +89,9 @@ int virNetServerStart(virNetServerPtr srv); const char *virNetServerGetName(virNetServerPtr srv); +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.4.11

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 25bcbf4..5cd9e72 100644 --- a/include/libvirt/libvirt-admin.h +++ b/include/libvirt/libvirt-admin.h @@ -110,6 +110,48 @@ virAdmServerPtr virAdmConnectLookupServer(virAdmConnectPtr conn, const char *name, 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 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 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 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.4.11

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 | 44 ++++++++++++++++++++++++++++++++++++++++ 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 | 45 +++++++++++++++++++++++++++++++++++++++++ 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, 215 insertions(+), 1 deletion(-) diff --git a/daemon/admin.c b/daemon/admin.c index 18ac22b..2510e4f 100644 --- a/daemon/admin.c +++ b/daemon/admin.c @@ -134,4 +134,48 @@ adminConnectGetLibVersion(virNetDaemonPtr dmn ATTRIBUTE_UNUSED, return 0; } +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 e2ed1fe..56fa4b5 100644 --- a/daemon/admin_server.c +++ b/daemon/admin_server.c @@ -69,3 +69,44 @@ adminConnectLookupServer(virNetDaemonPtr dmn, return virNetDaemonGetServer(dmn, name); } + +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 9d0adf0..f172474 100644 --- a/daemon/admin_server.h +++ b/daemon/admin_server.h @@ -35,4 +35,9 @@ virNetServerPtr adminConnectLookupServer(virNetDaemonPtr dmn, const char *name, 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 5cd9e72..faf57ad 100644 --- a/include/libvirt/libvirt-admin.h +++ b/include/libvirt/libvirt-admin.h @@ -152,6 +152,11 @@ virAdmServerPtr virAdmConnectLookupServer(virAdmConnectPtr conn, # 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 57dbb6b..f907b87 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 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>; @@ -98,6 +101,15 @@ struct admin_connect_lookup_server_ret { admin_nonnull_server srv; }; +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; @@ -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_CLIENT_PROCESSING_CONTROLS = 6 }; diff --git a/src/admin/admin_remote.c b/src/admin/admin_remote.c index a1b2f84..d56237d 100644 --- a/src/admin/admin_remote.c +++ b/src/admin/admin_remote.c @@ -39,6 +39,12 @@ struct _remoteAdminPriv { static virClassPtr remoteAdminPrivClass; static void +make_nonnull_server(admin_nonnull_server *srv_dst, virAdmServerPtr srv_src) +{ + srv_dst->name = srv_src->name; +} + +static void remoteAdminPrivDispose(void *opaque) { remoteAdminPrivPtr priv = opaque; @@ -225,3 +231,42 @@ remoteAdminPrivNew(const char *sock_path) virObjectUnref(priv); return NULL; } + +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 26c8443..b248a37 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_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, ADMIN_PROC_CONNECT_GET_LIB_VERSION = 3, ADMIN_PROC_CONNECT_LIST_SERVERS = 4, ADMIN_PROC_CONNECT_LOOKUP_SERVER = 5, + ADMIN_PROC_SERVER_GET_CLIENT_PROCESSING_CONTROLS = 6, }; diff --git a/src/libvirt-admin.c b/src/libvirt-admin.c index 6577c87..563d7d3 100644 --- a/src/libvirt-admin.c +++ b/src/libvirt-admin.c @@ -674,3 +674,46 @@ virAdmConnectLookupServer(virAdmConnectPtr conn, virDispatchError(NULL); return ret; } + +/** + * 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 268f1e6..ca08ff1 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_client_processing_controls_args; +xdr_admin_server_get_client_processing_controls_ret; # datatypes.h virAdmConnectClass; diff --git a/src/libvirt_admin_public.syms b/src/libvirt_admin_public.syms index 58d085e..c0e0da2 100644 --- a/src/libvirt_admin_public.syms +++ b/src/libvirt_admin_public.syms @@ -25,4 +25,5 @@ LIBVIRT_ADMIN_1.3.0 { virAdmServerGetName; virAdmServerFree; virAdmConnectLookupServer; + virAdmServerGetClientProcessingControls; }; -- 2.4.11

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 | 40 +++++++++++++++++++++++++++++++++++ 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, 227 insertions(+), 1 deletion(-) diff --git a/daemon/admin.c b/daemon/admin.c index 2510e4f..110ec84 100644 --- a/daemon/admin.c +++ b/daemon/admin.c @@ -178,4 +178,44 @@ adminDispatchServerGetClientProcessingControls(virNetServerPtr server ATTRIBUTE_ 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 56fa4b5..a9c6bf2 100644 --- a/daemon/admin_server.c +++ b/daemon/admin_server.c @@ -110,3 +110,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 f172474..31a3202 100644 --- a/daemon/admin_server.h +++ b/daemon/admin_server.h @@ -40,4 +40,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 faf57ad..113ecba 100644 --- a/include/libvirt/libvirt-admin.h +++ b/include/libvirt/libvirt-admin.h @@ -157,6 +157,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 f907b87..18e4552 100644 --- a/src/admin/admin_protocol.x +++ b/src/admin/admin_protocol.x @@ -110,6 +110,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; @@ -160,5 +166,10 @@ enum admin_procedure { /** * @generate: none */ - ADMIN_PROC_SERVER_GET_CLIENT_PROCESSING_CONTROLS = 6 + ADMIN_PROC_SERVER_GET_CLIENT_PROCESSING_CONTROLS = 6, + + /** + * @generate: none + */ + ADMIN_PROC_SERVER_SET_CLIENT_PROCESSING_CONTROLS = 7 }; diff --git a/src/admin/admin_remote.c b/src/admin/admin_remote.c index d56237d..e437141 100644 --- a/src/admin/admin_remote.c +++ b/src/admin/admin_remote.c @@ -270,3 +270,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 b248a37..5f68573 100644 --- a/src/admin_protocol-structs +++ b/src/admin_protocol-structs @@ -61,6 +61,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, @@ -68,4 +76,5 @@ enum admin_procedure { ADMIN_PROC_CONNECT_LIST_SERVERS = 4, ADMIN_PROC_CONNECT_LOOKUP_SERVER = 5, ADMIN_PROC_SERVER_GET_CLIENT_PROCESSING_CONTROLS = 6, + ADMIN_PROC_SERVER_SET_CLIENT_PROCESSING_CONTROLS = 7, }; diff --git a/src/libvirt-admin.c b/src/libvirt-admin.c index 563d7d3..17262e2 100644 --- a/src/libvirt-admin.c +++ b/src/libvirt-admin.c @@ -717,3 +717,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 ca08ff1..77415b2 100644 --- a/src/libvirt_admin_private.syms +++ b/src/libvirt_admin_private.syms @@ -14,6 +14,7 @@ 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_set_client_processing_controls_args; # datatypes.h virAdmConnectClass; diff --git a/src/libvirt_admin_public.syms b/src/libvirt_admin_public.syms index c0e0da2..f5498ee 100644 --- a/src/libvirt_admin_public.syms +++ b/src/libvirt_admin_public.syms @@ -26,4 +26,5 @@ LIBVIRT_ADMIN_1.3.0 { virAdmServerFree; virAdmConnectLookupServer; virAdmServerGetClientProcessingControls; + virAdmServerSetClientProcessingControls; }; diff --git a/src/rpc/virnetserver.c b/src/rpc/virnetserver.c index 38d807f..1d85ac9 100644 --- a/src/rpc/virnetserver.c +++ b/src/rpc/virnetserver.c @@ -925,3 +925,37 @@ virNetServerGetCurrentUnauthClients(virNetServerPtr srv) 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 770288d..2b1702f 100644 --- a/src/rpc/virnetserver.h +++ b/src/rpc/virnetserver.h @@ -94,4 +94,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.4.11

Finally wire-up the client processing controls APIs into virt-admin client. Signed-off-by: Erik Skultety <eskultet@redhat.com> --- tools/virt-admin.c | 182 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 182 insertions(+) diff --git a/tools/virt-admin.c b/tools/virt-admin.c index f0a49a3..3fe450e 100644 --- a/tools/virt-admin.c +++ b/tools/virt-admin.c @@ -353,6 +353,171 @@ cmdSrvList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) 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) { @@ -652,12 +817,29 @@ static const vshCmdDef monitoringCmds[] = { .info = info_srv_list, .flags = 0 }, + {.name = "srv-clients-info", + .handler = cmdSrvClientsInfo, + .opts = opts_srv_clients_info, + .info = info_srv_clients_info, + .flags = 0 + }, + {.name = NULL} +}; + +static const vshCmdDef managementCmds[] = { + {.name = "srv-clients-set", + .handler = cmdSrvClientsSet, + .opts = opts_srv_clients_set, + .info = info_srv_clients_set, + .flags = 0 + }, {.name = NULL} }; static const vshCmdGrp cmdGroups[] = { {"Virt-admin itself", "virt-admin", vshAdmCmds}, {"Monitoring commands", "monitor", monitoringCmds}, + {"Management commands", "management", managementCmds}, {NULL, NULL, NULL} }; -- 2.4.11

On 10/05/16 16:36, Michal Privoznik wrote:
On 10.04.2016 19:56, Erik Skultety wrote:
D'oh! Code has diverged too much to apply these cleanly. Can you please rebase and resend?
Michal
I forgot about this series when reposting the other rebased ones :/, I will respin a freshly rebased version in a moment, sorry for inconvenience. Erik
participants (2)
-
Erik Skultety
-
Michal Privoznik