mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-07-30 13:37:17 +00:00
daemon: Introduce max_anonymous_clients
https://bugzilla.redhat.com/show_bug.cgi?id=992980 This config tunable allows users to determine the maximum number of accepted but yet not authenticated users. Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
parent
4015396b2c
commit
68f60f669c
@ -258,7 +258,8 @@ daemonConfigNew(bool privileged ATTRIBUTE_UNUSED)
|
|||||||
|
|
||||||
data->min_workers = 5;
|
data->min_workers = 5;
|
||||||
data->max_workers = 20;
|
data->max_workers = 20;
|
||||||
data->max_clients = 20;
|
data->max_clients = 5000;
|
||||||
|
data->max_anonymous_clients = 20;
|
||||||
|
|
||||||
data->prio_workers = 5;
|
data->prio_workers = 5;
|
||||||
|
|
||||||
@ -415,6 +416,7 @@ daemonConfigLoadOptions(struct daemonConfig *data,
|
|||||||
GET_CONF_INT(conf, filename, max_workers);
|
GET_CONF_INT(conf, filename, max_workers);
|
||||||
GET_CONF_INT(conf, filename, max_clients);
|
GET_CONF_INT(conf, filename, max_clients);
|
||||||
GET_CONF_INT(conf, filename, max_queued_clients);
|
GET_CONF_INT(conf, filename, max_queued_clients);
|
||||||
|
GET_CONF_INT(conf, filename, max_anonymous_clients);
|
||||||
|
|
||||||
GET_CONF_INT(conf, filename, prio_workers);
|
GET_CONF_INT(conf, filename, prio_workers);
|
||||||
|
|
||||||
|
@ -64,6 +64,7 @@ struct daemonConfig {
|
|||||||
int max_workers;
|
int max_workers;
|
||||||
int max_clients;
|
int max_clients;
|
||||||
int max_queued_clients;
|
int max_queued_clients;
|
||||||
|
int max_anonymous_clients;
|
||||||
|
|
||||||
int prio_workers;
|
int prio_workers;
|
||||||
|
|
||||||
|
@ -57,6 +57,7 @@ module Libvirtd =
|
|||||||
| int_entry "max_workers"
|
| int_entry "max_workers"
|
||||||
| int_entry "max_clients"
|
| int_entry "max_clients"
|
||||||
| int_entry "max_queued_clients"
|
| int_entry "max_queued_clients"
|
||||||
|
| int_entry "max_anonymous_clients"
|
||||||
| int_entry "max_requests"
|
| int_entry "max_requests"
|
||||||
| int_entry "max_client_requests"
|
| int_entry "max_client_requests"
|
||||||
| int_entry "prio_workers"
|
| int_entry "prio_workers"
|
||||||
|
@ -1383,6 +1383,7 @@ int main(int argc, char **argv) {
|
|||||||
config->max_workers,
|
config->max_workers,
|
||||||
config->prio_workers,
|
config->prio_workers,
|
||||||
config->max_clients,
|
config->max_clients,
|
||||||
|
config->max_anonymous_clients,
|
||||||
config->keepalive_interval,
|
config->keepalive_interval,
|
||||||
config->keepalive_count,
|
config->keepalive_count,
|
||||||
!!config->keepalive_required,
|
!!config->keepalive_required,
|
||||||
|
@ -255,7 +255,7 @@
|
|||||||
|
|
||||||
# The maximum number of concurrent client connections to allow
|
# The maximum number of concurrent client connections to allow
|
||||||
# over all sockets combined.
|
# over all sockets combined.
|
||||||
#max_clients = 20
|
#max_clients = 5000
|
||||||
|
|
||||||
# The maximum length of queue of connections waiting to be
|
# The maximum length of queue of connections waiting to be
|
||||||
# accepted by the daemon. Note, that some protocols supporting
|
# accepted by the daemon. Note, that some protocols supporting
|
||||||
@ -263,6 +263,10 @@
|
|||||||
# connection succeeds.
|
# connection succeeds.
|
||||||
#max_queued_clients = 1000
|
#max_queued_clients = 1000
|
||||||
|
|
||||||
|
# The maximum length of queue of accepted but not yet not
|
||||||
|
# authenticated clients. The default value is zero, meaning
|
||||||
|
# the feature is disabled.
|
||||||
|
#max_anonymous_clients = 20
|
||||||
|
|
||||||
# The minimum limit sets the number of workers to start up
|
# The minimum limit sets the number of workers to start up
|
||||||
# initially. If the number of active clients exceeds this,
|
# initially. If the number of active clients exceeds this,
|
||||||
|
@ -34,8 +34,9 @@ module Test_libvirtd =
|
|||||||
{ "1" = "joe@EXAMPLE.COM" }
|
{ "1" = "joe@EXAMPLE.COM" }
|
||||||
{ "2" = "fred@EXAMPLE.COM" }
|
{ "2" = "fred@EXAMPLE.COM" }
|
||||||
}
|
}
|
||||||
{ "max_clients" = "20" }
|
{ "max_clients" = "5000" }
|
||||||
{ "max_queued_clients" = "1000" }
|
{ "max_queued_clients" = "1000" }
|
||||||
|
{ "max_anonymous_clients" = "20" }
|
||||||
{ "min_workers" = "5" }
|
{ "min_workers" = "5" }
|
||||||
{ "max_workers" = "20" }
|
{ "max_workers" = "20" }
|
||||||
{ "prio_workers" = "5" }
|
{ "prio_workers" = "5" }
|
||||||
|
@ -145,7 +145,7 @@ virLockDaemonNew(virLockDaemonConfigPtr config, bool privileged)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!(lockd->srv = virNetServerNew(1, 1, 0, config->max_clients,
|
if (!(lockd->srv = virNetServerNew(1, 1, 0, config->max_clients,
|
||||||
-1, 0,
|
config->max_clients, -1, 0,
|
||||||
false, NULL,
|
false, NULL,
|
||||||
virLockDaemonClientNew,
|
virLockDaemonClientNew,
|
||||||
virLockDaemonClientPreExecRestart,
|
virLockDaemonClientPreExecRestart,
|
||||||
|
@ -737,7 +737,7 @@ static int virLXCControllerSetupServer(virLXCControllerPtr ctrl)
|
|||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (!(ctrl->server = virNetServerNew(0, 0, 0, 1,
|
if (!(ctrl->server = virNetServerNew(0, 0, 0, 1,
|
||||||
-1, 0, false,
|
0, -1, 0, false,
|
||||||
NULL,
|
NULL,
|
||||||
virLXCControllerClientPrivateNew,
|
virLXCControllerClientPrivateNew,
|
||||||
NULL,
|
NULL,
|
||||||
|
@ -92,6 +92,7 @@ struct _virNetServer {
|
|||||||
virNetServerClientPtr *clients; /* Clients */
|
virNetServerClientPtr *clients; /* Clients */
|
||||||
size_t nclients_max; /* Max allowed clients count */
|
size_t nclients_max; /* Max allowed clients count */
|
||||||
size_t nclients_unauth; /* Unauthenticated clients count */
|
size_t nclients_unauth; /* Unauthenticated clients count */
|
||||||
|
size_t nclients_unauth_max; /* Max allowed unauth clients count */
|
||||||
|
|
||||||
int keepaliveInterval;
|
int keepaliveInterval;
|
||||||
unsigned int keepaliveCount;
|
unsigned int keepaliveCount;
|
||||||
@ -279,6 +280,14 @@ static int virNetServerAddClient(virNetServerPtr srv,
|
|||||||
if (virNetServerClientNeedAuth(client))
|
if (virNetServerClientNeedAuth(client))
|
||||||
virNetServerTrackPendingAuthLocked(srv);
|
virNetServerTrackPendingAuthLocked(srv);
|
||||||
|
|
||||||
|
if (srv->nclients_unauth_max &&
|
||||||
|
srv->nclients_unauth == srv->nclients_unauth_max) {
|
||||||
|
/* Temporarily stop accepting new clients */
|
||||||
|
VIR_DEBUG("Temporarily suspending services "
|
||||||
|
"due to max_anonymous_clients");
|
||||||
|
virNetServerUpdateServicesLocked(srv, false);
|
||||||
|
}
|
||||||
|
|
||||||
if (srv->nclients == srv->nclients_max) {
|
if (srv->nclients == srv->nclients_max) {
|
||||||
/* Temporarily stop accepting new clients */
|
/* Temporarily stop accepting new clients */
|
||||||
VIR_DEBUG("Temporarily suspending services due to max_clients");
|
VIR_DEBUG("Temporarily suspending services due to max_clients");
|
||||||
@ -362,6 +371,7 @@ virNetServerPtr virNetServerNew(size_t min_workers,
|
|||||||
size_t max_workers,
|
size_t max_workers,
|
||||||
size_t priority_workers,
|
size_t priority_workers,
|
||||||
size_t max_clients,
|
size_t max_clients,
|
||||||
|
size_t max_anonymous_clients,
|
||||||
int keepaliveInterval,
|
int keepaliveInterval,
|
||||||
unsigned int keepaliveCount,
|
unsigned int keepaliveCount,
|
||||||
bool keepaliveRequired,
|
bool keepaliveRequired,
|
||||||
@ -388,6 +398,7 @@ virNetServerPtr virNetServerNew(size_t min_workers,
|
|||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
srv->nclients_max = max_clients;
|
srv->nclients_max = max_clients;
|
||||||
|
srv->nclients_unauth_max = max_anonymous_clients;
|
||||||
srv->keepaliveInterval = keepaliveInterval;
|
srv->keepaliveInterval = keepaliveInterval;
|
||||||
srv->keepaliveCount = keepaliveCount;
|
srv->keepaliveCount = keepaliveCount;
|
||||||
srv->keepaliveRequired = keepaliveRequired;
|
srv->keepaliveRequired = keepaliveRequired;
|
||||||
@ -457,6 +468,7 @@ virNetServerPtr virNetServerNewPostExecRestart(virJSONValuePtr object,
|
|||||||
unsigned int max_workers;
|
unsigned int max_workers;
|
||||||
unsigned int priority_workers;
|
unsigned int priority_workers;
|
||||||
unsigned int max_clients;
|
unsigned int max_clients;
|
||||||
|
unsigned int max_anonymous_clients;
|
||||||
unsigned int keepaliveInterval;
|
unsigned int keepaliveInterval;
|
||||||
unsigned int keepaliveCount;
|
unsigned int keepaliveCount;
|
||||||
bool keepaliveRequired;
|
bool keepaliveRequired;
|
||||||
@ -482,6 +494,13 @@ virNetServerPtr virNetServerNewPostExecRestart(virJSONValuePtr object,
|
|||||||
_("Missing max_clients data in JSON document"));
|
_("Missing max_clients data in JSON document"));
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
if (virJSONValueObjectHasKey(object, "max_anonymous_clients") &&
|
||||||
|
virJSONValueObjectGetNumberUint(object, "max_anonymous_clients",
|
||||||
|
&max_anonymous_clients) < 0) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
|
_("Malformed max_anonymous_clients data in JSON document"));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
if (virJSONValueObjectGetNumberUint(object, "keepaliveInterval", &keepaliveInterval) < 0) {
|
if (virJSONValueObjectGetNumberUint(object, "keepaliveInterval", &keepaliveInterval) < 0) {
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
_("Missing keepaliveInterval data in JSON document"));
|
_("Missing keepaliveInterval data in JSON document"));
|
||||||
@ -507,6 +526,7 @@ virNetServerPtr virNetServerNewPostExecRestart(virJSONValuePtr object,
|
|||||||
|
|
||||||
if (!(srv = virNetServerNew(min_workers, max_clients,
|
if (!(srv = virNetServerNew(min_workers, max_clients,
|
||||||
priority_workers, max_clients,
|
priority_workers, max_clients,
|
||||||
|
max_anonymous_clients,
|
||||||
keepaliveInterval, keepaliveCount,
|
keepaliveInterval, keepaliveCount,
|
||||||
keepaliveRequired, mdnsGroupName,
|
keepaliveRequired, mdnsGroupName,
|
||||||
clientPrivNew, clientPrivPreExecRestart,
|
clientPrivNew, clientPrivPreExecRestart,
|
||||||
@ -625,6 +645,12 @@ virJSONValuePtr virNetServerPreExecRestart(virNetServerPtr srv)
|
|||||||
_("Cannot set max_clients data in JSON document"));
|
_("Cannot set max_clients data in JSON document"));
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
if (virJSONValueObjectAppendNumberUint(object, "max_anonymous_clients",
|
||||||
|
srv->nclients_unauth_max) < 0) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
|
_("Cannot set max_anonymous_clients data in JSON document"));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
if (virJSONValueObjectAppendNumberUint(object, "keepaliveInterval", srv->keepaliveInterval) < 0) {
|
if (virJSONValueObjectAppendNumberUint(object, "keepaliveInterval", srv->keepaliveInterval) < 0) {
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
_("Cannot set keepaliveInterval data in JSON document"));
|
_("Cannot set keepaliveInterval data in JSON document"));
|
||||||
@ -1068,6 +1094,34 @@ void virNetServerUpdateServices(virNetServerPtr srv,
|
|||||||
virObjectUnlock(srv);
|
virObjectUnlock(srv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* virNetServerCheckLimits:
|
||||||
|
* @srv: server to check limits on
|
||||||
|
*
|
||||||
|
* Check if limits like max_clients or max_anonymous_clients
|
||||||
|
* are satisfied and if so, re-enable accepting new clients.
|
||||||
|
* The @srv must be locked when this function is called.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
virNetServerCheckLimits(virNetServerPtr srv)
|
||||||
|
{
|
||||||
|
/* Enable services if we can accept a new client.
|
||||||
|
* The new client can be accepted if both max_clients and
|
||||||
|
* max_anonymous_clients wouldn't get overcommitted by
|
||||||
|
* accepting it. */
|
||||||
|
VIR_DEBUG("Considering re-enabling services: "
|
||||||
|
"nclients=%zu nclients_max=%zu "
|
||||||
|
"nclients_unauth=%zu nclients_unauth_max=%zu",
|
||||||
|
srv->nclients, srv->nclients_max,
|
||||||
|
srv->nclients_unauth, srv->nclients_unauth_max);
|
||||||
|
if (srv->nclients < srv->nclients_max &&
|
||||||
|
(!srv->nclients_unauth_max ||
|
||||||
|
srv->nclients_unauth < srv->nclients_unauth_max)) {
|
||||||
|
/* Now it makes sense to accept() a new client. */
|
||||||
|
VIR_DEBUG("Re-enabling services");
|
||||||
|
virNetServerUpdateServicesLocked(srv, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void virNetServerRun(virNetServerPtr srv)
|
void virNetServerRun(virNetServerPtr srv)
|
||||||
{
|
{
|
||||||
@ -1142,13 +1196,7 @@ void virNetServerRun(virNetServerPtr srv)
|
|||||||
if (virNetServerClientNeedAuth(client))
|
if (virNetServerClientNeedAuth(client))
|
||||||
virNetServerTrackCompletedAuthLocked(srv);
|
virNetServerTrackCompletedAuthLocked(srv);
|
||||||
|
|
||||||
/* Enable services if we can accept a new client.
|
virNetServerCheckLimits(srv);
|
||||||
* The new client can be accepted if we are at the limit. */
|
|
||||||
if (srv->nclients == srv->nclients_max - 1) {
|
|
||||||
/* Now it makes sense to accept() a new client. */
|
|
||||||
VIR_DEBUG("Re-enabling services");
|
|
||||||
virNetServerUpdateServicesLocked(srv, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
virObjectUnlock(srv);
|
virObjectUnlock(srv);
|
||||||
virObjectUnref(client);
|
virObjectUnref(client);
|
||||||
@ -1265,6 +1313,7 @@ size_t virNetServerTrackCompletedAuth(virNetServerPtr srv)
|
|||||||
size_t ret;
|
size_t ret;
|
||||||
virObjectLock(srv);
|
virObjectLock(srv);
|
||||||
ret = virNetServerTrackCompletedAuthLocked(srv);
|
ret = virNetServerTrackCompletedAuthLocked(srv);
|
||||||
|
virNetServerCheckLimits(srv);
|
||||||
virObjectUnlock(srv);
|
virObjectUnlock(srv);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,7 @@ virNetServerPtr virNetServerNew(size_t min_workers,
|
|||||||
size_t max_workers,
|
size_t max_workers,
|
||||||
size_t priority_workers,
|
size_t priority_workers,
|
||||||
size_t max_clients,
|
size_t max_clients,
|
||||||
|
size_t max_anonymous_clients,
|
||||||
int keepaliveInterval,
|
int keepaliveInterval,
|
||||||
unsigned int keepaliveCount,
|
unsigned int keepaliveCount,
|
||||||
bool keepaliveRequired,
|
bool keepaliveRequired,
|
||||||
|
Loading…
Reference in New Issue
Block a user