|
|
43fe83 |
From f5e317a62939f1b06081f309ee4e7b146385509b Mon Sep 17 00:00:00 2001
|
|
|
43fe83 |
Message-Id: <f5e317a62939f1b06081f309ee4e7b146385509b.1377873636.git.jdenemar@redhat.com>
|
|
|
43fe83 |
From: Michal Privoznik <mprivozn@redhat.com>
|
|
|
43fe83 |
Date: Mon, 5 Aug 2013 11:30:16 +0200
|
|
|
43fe83 |
Subject: [PATCH] RPC: Don't accept client if it would overcommit max_clients
|
|
|
43fe83 |
|
|
|
43fe83 |
https://bugzilla.redhat.com/show_bug.cgi?id=981729
|
|
|
43fe83 |
|
|
|
43fe83 |
Currently, even if max_client limit is hit, we accept() incoming
|
|
|
43fe83 |
connection request, but close it immediately. This has disadvantage of
|
|
|
43fe83 |
not using listen() queue. We should accept() only those clients we
|
|
|
43fe83 |
know we can serve and let all other wait in the (limited) queue.
|
|
|
43fe83 |
(cherry picked from commit 2737aaafe953fc63c3387aa3ecc540b0f44c735c)
|
|
|
43fe83 |
---
|
|
|
43fe83 |
src/rpc/virnetserver.c | 29 ++++++++++++++++++++++++++---
|
|
|
43fe83 |
1 file changed, 26 insertions(+), 3 deletions(-)
|
|
|
43fe83 |
|
|
|
43fe83 |
diff --git a/src/rpc/virnetserver.c b/src/rpc/virnetserver.c
|
|
|
43fe83 |
index cb770c3..2306e10 100644
|
|
|
43fe83 |
--- a/src/rpc/virnetserver.c
|
|
|
43fe83 |
+++ b/src/rpc/virnetserver.c
|
|
|
43fe83 |
@@ -115,6 +115,8 @@ struct _virNetServer {
|
|
|
43fe83 |
|
|
|
43fe83 |
static virClassPtr virNetServerClass;
|
|
|
43fe83 |
static void virNetServerDispose(void *obj);
|
|
|
43fe83 |
+static void virNetServerUpdateServicesLocked(virNetServerPtr srv,
|
|
|
43fe83 |
+ bool enabled);
|
|
|
43fe83 |
|
|
|
43fe83 |
static int virNetServerOnceInit(void)
|
|
|
43fe83 |
{
|
|
|
43fe83 |
@@ -270,6 +272,12 @@ static int virNetServerAddClient(virNetServerPtr srv,
|
|
|
43fe83 |
srv->clients[srv->nclients-1] = client;
|
|
|
43fe83 |
virObjectRef(client);
|
|
|
43fe83 |
|
|
|
43fe83 |
+ if (srv->nclients == srv->nclients_max) {
|
|
|
43fe83 |
+ /* Temporarily stop accepting new clients */
|
|
|
43fe83 |
+ VIR_DEBUG("Temporarily suspending services due to max_clients");
|
|
|
43fe83 |
+ virNetServerUpdateServicesLocked(srv, false);
|
|
|
43fe83 |
+ }
|
|
|
43fe83 |
+
|
|
|
43fe83 |
virNetServerClientSetDispatcher(client,
|
|
|
43fe83 |
virNetServerDispatchNewMessage,
|
|
|
43fe83 |
srv);
|
|
|
43fe83 |
@@ -1034,15 +1042,22 @@ static void virNetServerAutoShutdownTimer(int timerid ATTRIBUTE_UNUSED,
|
|
|
43fe83 |
}
|
|
|
43fe83 |
|
|
|
43fe83 |
|
|
|
43fe83 |
-void virNetServerUpdateServices(virNetServerPtr srv,
|
|
|
43fe83 |
- bool enabled)
|
|
|
43fe83 |
+static void
|
|
|
43fe83 |
+virNetServerUpdateServicesLocked(virNetServerPtr srv,
|
|
|
43fe83 |
+ bool enabled)
|
|
|
43fe83 |
{
|
|
|
43fe83 |
size_t i;
|
|
|
43fe83 |
|
|
|
43fe83 |
- virObjectLock(srv);
|
|
|
43fe83 |
for (i = 0; i < srv->nservices; i++)
|
|
|
43fe83 |
virNetServerServiceToggle(srv->services[i], enabled);
|
|
|
43fe83 |
+}
|
|
|
43fe83 |
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+void virNetServerUpdateServices(virNetServerPtr srv,
|
|
|
43fe83 |
+ bool enabled)
|
|
|
43fe83 |
+{
|
|
|
43fe83 |
+ virObjectLock(srv);
|
|
|
43fe83 |
+ virNetServerUpdateServicesLocked(srv, enabled);
|
|
|
43fe83 |
virObjectUnlock(srv);
|
|
|
43fe83 |
}
|
|
|
43fe83 |
|
|
|
43fe83 |
@@ -1120,6 +1135,14 @@ void virNetServerRun(virNetServerPtr srv)
|
|
|
43fe83 |
srv->nclients = 0;
|
|
|
43fe83 |
}
|
|
|
43fe83 |
|
|
|
43fe83 |
+ /* Enable services if we can accept a new client.
|
|
|
43fe83 |
+ * The new client can be accepted if we are at the limit. */
|
|
|
43fe83 |
+ if (srv->nclients == srv->nclients_max - 1) {
|
|
|
43fe83 |
+ /* Now it makes sense to accept() a new client. */
|
|
|
43fe83 |
+ VIR_DEBUG("Re-enabling services");
|
|
|
43fe83 |
+ virNetServerUpdateServicesLocked(srv, true);
|
|
|
43fe83 |
+ }
|
|
|
43fe83 |
+
|
|
|
43fe83 |
virObjectUnlock(srv);
|
|
|
43fe83 |
virObjectUnref(client);
|
|
|
43fe83 |
virObjectLock(srv);
|
|
|
43fe83 |
--
|
|
|
43fe83 |
1.8.3.2
|
|
|
43fe83 |
|