mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-12 13:17:58 +03:00
RPC: Don't accept client if it would overcommit max_clients
Currently, even if max_client limit is hit, we accept() incoming connection request, but close it immediately. This has disadvantage of not using listen() queue. We should accept() only those clients we know we can serve and let all other wait in the (limited) queue.
This commit is contained in:
parent
3bb0125766
commit
2737aaafe9
@ -115,6 +115,8 @@ struct _virNetServer {
|
||||
|
||||
static virClassPtr virNetServerClass;
|
||||
static void virNetServerDispose(void *obj);
|
||||
static void virNetServerUpdateServicesLocked(virNetServerPtr srv,
|
||||
bool enabled);
|
||||
|
||||
static int virNetServerOnceInit(void)
|
||||
{
|
||||
@ -270,6 +272,12 @@ static int virNetServerAddClient(virNetServerPtr srv,
|
||||
srv->clients[srv->nclients-1] = client;
|
||||
virObjectRef(client);
|
||||
|
||||
if (srv->nclients == srv->nclients_max) {
|
||||
/* Temporarily stop accepting new clients */
|
||||
VIR_DEBUG("Temporarily suspending services due to max_clients");
|
||||
virNetServerUpdateServicesLocked(srv, false);
|
||||
}
|
||||
|
||||
virNetServerClientSetDispatcher(client,
|
||||
virNetServerDispatchNewMessage,
|
||||
srv);
|
||||
@ -1034,15 +1042,22 @@ static void virNetServerAutoShutdownTimer(int timerid ATTRIBUTE_UNUSED,
|
||||
}
|
||||
|
||||
|
||||
void virNetServerUpdateServices(virNetServerPtr srv,
|
||||
static void
|
||||
virNetServerUpdateServicesLocked(virNetServerPtr srv,
|
||||
bool enabled)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
virObjectLock(srv);
|
||||
for (i = 0; i < srv->nservices; i++)
|
||||
virNetServerServiceToggle(srv->services[i], enabled);
|
||||
}
|
||||
|
||||
|
||||
void virNetServerUpdateServices(virNetServerPtr srv,
|
||||
bool enabled)
|
||||
{
|
||||
virObjectLock(srv);
|
||||
virNetServerUpdateServicesLocked(srv, enabled);
|
||||
virObjectUnlock(srv);
|
||||
}
|
||||
|
||||
@ -1120,6 +1135,14 @@ void virNetServerRun(virNetServerPtr srv)
|
||||
srv->nclients = 0;
|
||||
}
|
||||
|
||||
/* Enable services if we can accept a new client.
|
||||
* 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);
|
||||
virObjectUnref(client);
|
||||
virObjectLock(srv);
|
||||
|
Loading…
Reference in New Issue
Block a user