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(a)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