This defaults to 20 -- the same as the current hardcoded option.

Signed-off-by: Brian Foley <[email protected]>
---
 lib/http/server.py   | 11 ++++++++---
 lib/server/noded.py  | 22 ++++++++++++++++------
 lib/server/rapi.py   | 16 ++++++++++++----
 man/ganeti-noded.rst | 10 ++++++++--
 man/ganeti-rapi.rst  |  7 ++++++-
 5 files changed, 50 insertions(+), 16 deletions(-)

diff --git a/lib/http/server.py b/lib/http/server.py
index 9a4563e..b4a41c8 100644
--- a/lib/http/server.py
+++ b/lib/http/server.py
@@ -479,9 +479,8 @@ class HttpServer(http.HttpBase, asyncore.dispatcher):
   """Generic HTTP server class
 
   """
-  MAX_CHILDREN = 20
 
-  def __init__(self, mainloop, local_address, port, handler,
+  def __init__(self, mainloop, local_address, port, max_clients, handler,
                ssl_params=None, ssl_verify_peer=False,
                request_executor_class=None, ssl_verify_callback=None):
     """Initializes the HTTP server
@@ -492,6 +491,11 @@ class HttpServer(http.HttpBase, asyncore.dispatcher):
     @param local_address: Local IP address to bind to
     @type port: int
     @param port: TCP port to listen on
+    @type max_clients: int
+    @param max_clients: maximum number of client connections
+        open simultaneously.
+    @type handler: HttpServerHandler
+    @param handler: Request handler object
     @type ssl_params: HttpSslParams
     @param ssl_params: SSL key and certificate
     @type ssl_verify_peer: bool
@@ -524,6 +528,7 @@ class HttpServer(http.HttpBase, asyncore.dispatcher):
     self._children = []
     self.set_socket(self.socket)
     self.accepting = True
+    self.max_clients = max_clients
     mainloop.RegisterSignal(self)
 
   def Start(self):
@@ -549,7 +554,7 @@ class HttpServer(http.HttpBase, asyncore.dispatcher):
     """
     if not quick:
       # Don't wait for other processes if it should be a quick check
-      while len(self._children) > self.MAX_CHILDREN:
+      while len(self._children) > self.max_clients:
         try:
           # Waiting without a timeout brings us into a potential DoS situation.
           # As soon as too many children run, we'll not respond to new
diff --git a/lib/server/noded.py b/lib/server/noded.py
index a5e05dd..9375fa0 100644
--- a/lib/server/noded.py
+++ b/lib/server/noded.py
@@ -1283,7 +1283,7 @@ class NodeRequestHandler(http.server.HttpServerHandler):
     return backend.CleanupImportExport(params[0])
 
 
-def CheckNoded(_, args):
+def CheckNoded(options, args):
   """Initial checks whether to run or exit with a failure.
 
   """
@@ -1291,6 +1291,12 @@ def CheckNoded(_, args):
     print >> sys.stderr, ("Usage: %s [-f] [-d] [-p port] [-b ADDRESS]" %
                           sys.argv[0])
     sys.exit(constants.EXIT_FAILURE)
+
+  if options.max_clients < 1:
+    print >> sys.stderr, ("%s --max-clients argument must be >= 1" %
+                          sys.argv[0])
+    sys.exit(constants.EXIT_FAILURE)
+
   try:
     codecs.lookup("string-escape")
   except LookupError:
@@ -1404,11 +1410,11 @@ def PrepNoded(options, _):
   handler = NodeRequestHandler()
 
   mainloop = daemon.Mainloop()
-  server = \
-    http.server.HttpServer(mainloop, options.bind_address, options.port,
-                           handler, ssl_params=ssl_params, 
ssl_verify_peer=True,
-                           request_executor_class=request_executor_class,
-                           ssl_verify_callback=SSLVerifyPeer)
+  server = http.server.HttpServer(
+      mainloop, options.bind_address, options.port, options.max_clients,
+      handler, ssl_params=ssl_params, ssl_verify_peer=True,
+      request_executor_class=request_executor_class,
+      ssl_verify_callback=SSLVerifyPeer)
   server.Start()
 
   return (mainloop, server)
@@ -1437,6 +1443,10 @@ def Main():
   parser.add_option("--no-mlock", dest="mlock",
                     help="Do not mlock the node memory in ram",
                     default=True, action="store_false")
+  parser.add_option("--max-clients", dest="max_clients",
+                    default=20, type="int",
+                    help="Number of simultaneous connections accepted"
+                    " by noded")
 
   daemon.GenericMain(constants.NODED, parser, CheckNoded, PrepNoded, ExecNoded,
                      default_ssl_cert=pathutils.NODED_CERT_FILE,
diff --git a/lib/server/rapi.py b/lib/server/rapi.py
index 9782ada..fc1d27c 100644
--- a/lib/server/rapi.py
+++ b/lib/server/rapi.py
@@ -318,6 +318,11 @@ def CheckRapi(options, args):
                           sys.argv[0])
     sys.exit(constants.EXIT_FAILURE)
 
+  if options.max_clients < 1:
+    print >> sys.stderr, ("%s --max-clients argument must be >= 1" %
+                          sys.argv[0])
+    sys.exit(constants.EXIT_FAILURE)
+
   ssconf.CheckMaster(options.debug)
 
   # Read SSL certificate (this is a little hackish to read the cert as root)
@@ -344,10 +349,9 @@ def PrepRapi(options, _):
 
   users.Load(pathutils.RAPI_USERS_FILE)
 
-  server = \
-    http.server.HttpServer(mainloop, options.bind_address, options.port,
-                           handler,
-                           ssl_params=options.ssl_params, 
ssl_verify_peer=False)
+  server = http.server.HttpServer(
+      mainloop, options.bind_address, options.port, options.max_clients,
+      handler, ssl_params=options.ssl_params, ssl_verify_peer=False)
   server.Start()
 
   return (mainloop, server)
@@ -377,6 +381,10 @@ def Main():
                     default=False, action="store_true",
                     help=("Disable anonymous HTTP requests and require"
                           " authentication"))
+  parser.add_option("--max-clients", dest="max_clients",
+                    default=20, type="int",
+                    help="Number of simultaneous connections accepted"
+                    " by ganeti-rapi")
 
   daemon.GenericMain(constants.RAPI, parser, CheckRapi, PrepRapi, ExecRapi,
                      default_ssl_cert=pathutils.RAPI_CERT_FILE,
diff --git a/man/ganeti-noded.rst b/man/ganeti-noded.rst
index 3321cb8..df725e4 100644
--- a/man/ganeti-noded.rst
+++ b/man/ganeti-noded.rst
@@ -9,8 +9,9 @@ ganeti-noded - Ganeti node daemon
 Synopsis
 --------
 
-**ganeti-noded** [-f] [-d] [-p *PORT*] [-b *ADDRESS*] [-i *INTERFACE*]
-[--no-mlock] [--syslog] [--no-ssl] [-K *SSL_KEY_FILE*] [-C *SSL_CERT_FILE*]
+| **ganeti-noded** [-f] [-d] [-p *PORT*] [-b *ADDRESS*] [-i *INTERFACE*]
+| [\--max-clients *CLIENTS*] [\--no-mlock] [\--syslog] [\--no-ssl]
+| [-K *SSL_KEY_FILE*] [-C *SSL_CERT_FILE*]
 
 DESCRIPTION
 -----------
@@ -38,6 +39,11 @@ option.  The ``-b`` option can be used to specify the 
address to bind
 to (defaults to ``0.0.0.0``); alternatively, the ``-i`` option can be
 used to specify the interface to bind do.
 
+The maximum number of simultaneous client connections may be configured
+with the ``--max-clients`` option. This defaults to 20. Connections
+above this count are accepted, but no responses are sent until enough
+connections are closed.
+
 Ganeti noded communication is protected via SSL, with a key
 generated at cluster init time. This can be disabled with the
 ``--no-ssl`` option, or a different SSL key and certificate can be
diff --git a/man/ganeti-rapi.rst b/man/ganeti-rapi.rst
index 3cded7b..2111f82 100644
--- a/man/ganeti-rapi.rst
+++ b/man/ganeti-rapi.rst
@@ -10,7 +10,7 @@ Synopsis
 --------
 
 | **ganeti-rapi** [-d] [-f] [-p *PORT*] [-b *ADDRESS*] [-i *INTERFACE*]
-| [\--no-ssl] [-K *SSL_KEY_FILE*] [-C *SSL_CERT_FILE*]
+| [\--max-clients] [\--no-ssl] [-K *SSL_KEY_FILE*] [-C *SSL_CERT_FILE*]
 | [\--require-authentication]
 
 DESCRIPTION
@@ -34,6 +34,11 @@ it will not be able to reach the RAPI interface and will 
attempt to
 restart it all the time. Alternatively to setting the IP with ``--b``,
 the ``-i`` option can be used to specify the interface to bind do.
 
+The maximum number of simultaneous client connections may be configured
+with the ``--max-clients`` option. This defaults to 20. Connections
+above this count are accepted, but no responses are sent until enough
+connections are closed.
+
 See the *Ganeti remote API* documentation for further information.
 
 Requests are logged to ``@LOCALSTATEDIR@/log/ganeti/rapi-daemon.log``,
-- 
2.8.0.rc3.226.g39d4020

Reply via email to