admin: Introduce virAdmServerSetClientLimits

Opposite operation to virAdmServerGetClientLimits. 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>
This commit is contained in:
Erik Skultety 2016-04-04 14:24:52 +02:00
parent 509bd5d8b3
commit 8b1f04693d
12 changed files with 223 additions and 1 deletions

View File

@ -345,4 +345,42 @@ adminDispatchServerGetClientLimits(virNetServerPtr server ATTRIBUTE_UNUSED,
virObjectUnref(srv); virObjectUnref(srv);
return rv; return rv;
} }
static int
adminDispatchServerSetClientLimits(virNetServerPtr server ATTRIBUTE_UNUSED,
virNetServerClientPtr client,
virNetMessagePtr msg ATTRIBUTE_UNUSED,
virNetMessageErrorPtr rerr ATTRIBUTE_UNUSED,
admin_server_set_client_limits_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_LIMITS_MAX, &params, &nparams) < 0)
goto cleanup;
if (adminServerSetClientLimits(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" #include "admin_dispatch.h"

View File

@ -352,3 +352,38 @@ adminServerGetClientLimits(virNetServerPtr srv,
virTypedParamsFree(tmpparams, *nparams); virTypedParamsFree(tmpparams, *nparams);
return ret; return ret;
} }
int
adminServerSetClientLimits(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;
}

View File

@ -67,4 +67,9 @@ int adminServerGetClientLimits(virNetServerPtr srv,
int *nparams, int *nparams,
unsigned int flags); unsigned int flags);
int adminServerSetClientLimits(virNetServerPtr srv,
virTypedParameterPtr params,
int nparams,
unsigned int flags);
#endif /* __LIBVIRTD_ADMIN_SERVER_H__ */ #endif /* __LIBVIRTD_ADMIN_SERVER_H__ */

View File

@ -398,6 +398,11 @@ int virAdmServerGetClientLimits(virAdmServerPtr srv,
int *nparams, int *nparams,
unsigned int flags); unsigned int flags);
int virAdmServerSetClientLimits(virAdmServerPtr srv,
virTypedParameterPtr params,
int nparams,
unsigned int flags);
# ifdef __cplusplus # ifdef __cplusplus
} }
# endif # endif

View File

@ -177,6 +177,12 @@ struct admin_server_get_client_limits_ret {
admin_typed_param params<ADMIN_SERVER_CLIENT_LIMITS_MAX>; admin_typed_param params<ADMIN_SERVER_CLIENT_LIMITS_MAX>;
}; };
struct admin_server_set_client_limits_args {
admin_nonnull_server srv;
admin_typed_param params<ADMIN_SERVER_CLIENT_LIMITS_MAX>;
unsigned int flags;
};
/* Define the program number, protocol version and procedure numbers here. */ /* Define the program number, protocol version and procedure numbers here. */
const ADMIN_PROGRAM = 0x06900690; const ADMIN_PROGRAM = 0x06900690;
const ADMIN_PROTOCOL_VERSION = 1; const ADMIN_PROTOCOL_VERSION = 1;
@ -257,5 +263,10 @@ enum admin_procedure {
/** /**
* @generate: none * @generate: none
*/ */
ADMIN_PROC_SERVER_GET_CLIENT_LIMITS = 12 ADMIN_PROC_SERVER_GET_CLIENT_LIMITS = 12,
/**
* @generate: none
*/
ADMIN_PROC_SERVER_SET_CLIENT_LIMITS = 13
}; };

View File

@ -394,3 +394,38 @@ remoteAdminServerGetClientLimits(virAdmServerPtr srv,
virObjectUnlock(priv); virObjectUnlock(priv);
return rv; return rv;
} }
static int
remoteAdminServerSetClientLimits(virAdmServerPtr srv,
virTypedParameterPtr params,
int nparams,
unsigned int flags)
{
int rv = -1;
admin_server_set_client_limits_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_LIMITS,
(xdrproc_t) xdr_admin_server_set_client_limits_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;
}

View File

@ -119,6 +119,14 @@ struct admin_server_get_client_limits_ret {
admin_typed_param * params_val; admin_typed_param * params_val;
} params; } params;
}; };
struct admin_server_set_client_limits_args {
admin_nonnull_server srv;
struct {
u_int params_len;
admin_typed_param * params_val;
} params;
u_int flags;
};
enum admin_procedure { enum admin_procedure {
ADMIN_PROC_CONNECT_OPEN = 1, ADMIN_PROC_CONNECT_OPEN = 1,
ADMIN_PROC_CONNECT_CLOSE = 2, ADMIN_PROC_CONNECT_CLOSE = 2,
@ -132,4 +140,5 @@ enum admin_procedure {
ADMIN_PROC_CLIENT_GET_INFO = 10, ADMIN_PROC_CLIENT_GET_INFO = 10,
ADMIN_PROC_CLIENT_CLOSE = 11, ADMIN_PROC_CLIENT_CLOSE = 11,
ADMIN_PROC_SERVER_GET_CLIENT_LIMITS = 12, ADMIN_PROC_SERVER_GET_CLIENT_LIMITS = 12,
ADMIN_PROC_SERVER_SET_CLIENT_LIMITS = 13,
}; };

View File

@ -1041,3 +1041,47 @@ virAdmServerGetClientLimits(virAdmServerPtr srv,
virDispatchError(NULL); virDispatchError(NULL);
return -1; return -1;
} }
/**
* virAdmServerSetClientLimits:
* @srv: a valid server object reference
* @params: pointer to client limits object
* @nparams: number of parameters in @params
* @flags: extra flags; not used yet, so callers should always pass 0
*
* Change client limits configuration on server @srv.
*
* Caller is responsible for allocating @params prior to calling this function.
* See 'Manage per-server client limits' in libvirt-admin.h for
* supported parameters in @params.
*
* Returns 0 if the limits have been changed successfully or -1 in case of an
* error.
*/
int
virAdmServerSetClientLimits(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);
virCheckNonNegativeArgGoto(nparams, error);
if ((ret = remoteAdminServerSetClientLimits(srv, params, nparams,
flags)) < 0)
goto error;
return ret;
error:
virDispatchError(NULL);
return ret;
}

View File

@ -23,6 +23,7 @@ xdr_admin_server_list_clients_args;
xdr_admin_server_list_clients_ret; xdr_admin_server_list_clients_ret;
xdr_admin_server_lookup_client_args; xdr_admin_server_lookup_client_args;
xdr_admin_server_lookup_client_ret; xdr_admin_server_lookup_client_ret;
xdr_admin_server_set_client_limits_args;
xdr_admin_server_set_threadpool_parameters_args; xdr_admin_server_set_threadpool_parameters_args;
# datatypes.h # datatypes.h

View File

@ -36,4 +36,5 @@ LIBVIRT_ADMIN_1.3.0 {
virAdmClientGetInfo; virAdmClientGetInfo;
virAdmClientClose; virAdmClientClose;
virAdmServerGetClientLimits; virAdmServerGetClientLimits;
virAdmServerSetClientLimits;
}; };

View File

@ -1044,3 +1044,37 @@ virNetServerGetClient(virNetServerPtr srv,
_("No client with matching ID '%llu'"), id); _("No client with matching ID '%llu'"), id);
return ret; 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;
}

View File

@ -116,4 +116,8 @@ size_t virNetServerGetCurrentClients(virNetServerPtr srv);
size_t virNetServerGetMaxUnauthClients(virNetServerPtr srv); size_t virNetServerGetMaxUnauthClients(virNetServerPtr srv);
size_t virNetServerGetCurrentUnauthClients(virNetServerPtr srv); size_t virNetServerGetCurrentUnauthClients(virNetServerPtr srv);
int virNetServerSetClientProcessingControls(virNetServerPtr srv,
long long int maxClients,
long long int maxClientsUnauth);
#endif /* __VIR_NET_SERVER_H__ */ #endif /* __VIR_NET_SERVER_H__ */