This patch adds 3 new configuration variables to allow the number of
threads to be tuned, and also to limit the number of server connections
from clients.

# The maximum number of concurrent client connections to allow
# over all sockets combined.
# max_clients = 20


# The minimum limit sets the number of workers to start up
# initially. If the number of active clients exceeds this,
# then more threads are spawned, upto max_workers limit.
# Typically you'd want max_workers to equal maximum number
# of clients allowed
#min_workers = 5
#max_workers = 20


NB, this patch does not yet implement the logic to automatically spawn
more threads upto 'max_workers' - its currently just fixed at the initial
'min_workers' level. I'll address this next time I post it.


One question I'd like opinions on, is whether we should have separate
'max client' limits for the local UNIX socket, vs the remotely accessible
TCP/TLS sockets ?

Or alternatively, follow the postgresql practice, of always allowing the
'root' user to connect to the UNIX socket regardless of limits. Only
applying the limits to non-root users on UNIX socket, and TCP sockets

 libvirtd.aug      |    6 ++++++
 libvirtd.conf     |   19 +++++++++++++++++++
 qemud.c           |   18 +++++++++++++++++-
 test_libvirtd.aug |   38 ++++++++++++++++++++++++++++++++++++++
 4 files changed, 80 insertions(+), 1 deletion(-)


Daniel

diff --git a/qemud/libvirtd.aug b/qemud/libvirtd.aug
--- a/qemud/libvirtd.aug
+++ b/qemud/libvirtd.aug
@@ -13,11 +13,13 @@ module Libvirtd =
 
    let str_val = del /\"/ "\"" . store /[^\"]*/ . del /\"/ "\""
    let bool_val = store /0|1/
+   let int_val = store /[0-9]+/
    let str_array_element = [ seq "el" . str_val ] . del /[ \t\n]*/ ""
    let str_array_val = counter "el" . array_start . ( str_array_element . ( 
array_sep . str_array_element ) * ) ? . array_end
 
    let str_entry       (kw:string) = [ key kw . value_sep . str_val ]
    let bool_entry      (kw:string) = [ key kw . value_sep . bool_val ]
+   let int_entry      (kw:string) = [ key kw . value_sep . int_val ]
    let str_array_entry (kw:string) = [ key kw . value_sep . str_array_val ]
 
 
@@ -48,6 +50,9 @@ module Libvirtd =
                            | str_array_entry "tls_allowed_dn_list"
                            | str_array_entry "sasl_allowed_username_list"
 
+   let processing_entry = int_entry "min_workers"
+                        | int_entry "max_workers"
+                        | int_entry "max_clients"
 
    (* Each enty in the config is one of the following three ... *)
    let entry = network_entry
@@ -55,6 +60,7 @@ module Libvirtd =
              | authentication_entry
              | certificate_entry
              | authorization_entry
+             | processing_entry
    let comment = [ label "#comment" . del /#[ \t]*/ "# " .  store /([^ 
\t\n][^\n]*)?/ . del /\n/ "\n" ]
    let empty = [ label "#empty" . eol ]
 
diff --git a/qemud/libvirtd.conf b/qemud/libvirtd.conf
--- a/qemud/libvirtd.conf
+++ b/qemud/libvirtd.conf
@@ -225,3 +225,22 @@
 #sasl_allowed_username_list = ["[EMAIL PROTECTED]", "[EMAIL PROTECTED]" ]
 
 
+
+#################################################################
+#
+# Processing controls
+#
+
+# The maximum number of concurrent client connections to allow
+# over all sockets combined.
+# max_clients = 20
+
+
+# The minimum limit sets the number of workers to start up
+# initially. If the number of active clients exceeds this,
+# then more threads are spawned, upto max_workers limit.
+# Typically you'd want max_workers to equal maximum number
+# of clients allowed
+#min_workers = 5
+#max_workers = 20
+
diff --git a/qemud/qemud.c b/qemud/qemud.c
--- a/qemud/qemud.c
+++ b/qemud/qemud.c
@@ -105,6 +105,10 @@ static char *crl_file = (char *) "";
 
 static gnutls_certificate_credentials_t x509_cred;
 static gnutls_dh_params_t dh_params;
+
+static int min_workers = 5;
+static int max_workers = 20;
+static int max_clients = 20;
 
 #define DH_BITS 1024
 
@@ -1101,6 +1105,13 @@ static int qemudDispatchServer(struct qe
         qemudLog(QEMUD_ERR, _("Failed to accept connection: %s"), 
strerror(errno));
         return -1;
     }
+
+    if (server->nclients >= max_clients) {
+        qemudLog(QEMUD_ERR, "%s", _("Too many active clients, dropping 
connection"));
+        close(fd);
+        return -1;
+    }
+
     fprintf(stderr, "New client %d\n", fd);
     if (VIR_REALLOC_N(server->clients, server->nclients+1) < 0) {
         qemudLog(QEMUD_ERR, "%s", _("Out of memory allocating clients"));
@@ -1744,7 +1755,7 @@ static int qemudRunLoop(struct qemud_ser
 
     pthread_mutex_lock(&server->lock);
 
-    server->nworkers = 10;
+    server->nworkers = min_workers;
     if (VIR_ALLOC_N(server->workers, server->nworkers) < 0) {
         qemudLog(QEMUD_ERR, "%s", _("Failed to allocate workers"));
         return -1;
@@ -2137,6 +2148,11 @@ remoteReadConfigFile (struct qemud_serve
 
     if (remoteReadSaslAllowedUsernameList (conf, server, filename) < 0)
         goto free_and_fail;
+
+
+    GET_CONF_INT (conf, filename, min_workers);
+    GET_CONF_INT (conf, filename, max_workers);
+    GET_CONF_INT (conf, filename, max_clients);
 
     virConfFree (conf);
     return 0;
diff --git a/qemud/test_libvirtd.aug b/qemud/test_libvirtd.aug
--- a/qemud/test_libvirtd.aug
+++ b/qemud/test_libvirtd.aug
@@ -227,6 +227,25 @@ sasl_allowed_username_list = [
   \"[EMAIL PROTECTED]",
   \"[EMAIL PROTECTED]"
 ]
+
+
+#################################################################
+#
+# Processing controls
+#
+
+# The maximum number of concurrent client connections to allow
+# over all sockets combined.
+max_clients = 20
+
+
+# The minimum limit sets the number of workers to start up
+# initially. If the number of active clients exceeds this,
+# then more threads are spawned, upto max_workers limit.
+# Typically you'd want max_workers to equal maximum number
+# of clients allowed
+min_workers = 5
+max_workers = 20
 "
 
    test Libvirtd.lns get conf =
@@ -461,3 +480,22 @@ sasl_allowed_username_list = [
              { "1" = "[EMAIL PROTECTED]" }
              { "2" = "[EMAIL PROTECTED]" }
         }
+        { "#empty" }
+        { "#empty" }
+        { "#comment" = 
"################################################################"}
+        { "#comment" = ""}
+        { "#comment" = "Processing controls"}
+        { "#comment" = ""}
+        { "#empty" }
+        { "#comment" = "The maximum number of concurrent client connections to 
allow"}
+        { "#comment" = "over all sockets combined."}
+        { "max_clients" = "20" }
+        { "#empty" }
+        { "#empty" }
+        { "#comment" = "The minimum limit sets the number of workers to start 
up"}
+        { "#comment" = "initially. If the number of active clients exceeds 
this,"}
+        { "#comment" = "then more threads are spawned, upto max_workers 
limit."}
+        { "#comment" = "Typically you'd want max_workers to equal maximum 
number"}
+        { "#comment" = "of clients allowed"}
+        { "min_workers" = "5" }
+        { "max_workers" = "20" }

-- 
|: Red Hat, Engineering, London   -o-   http://people.redhat.com/berrange/ :|
|: http://libvirt.org  -o-  http://virt-manager.org  -o-  http://ovirt.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505  -o-  F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

--
Libvir-list mailing list
Libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Reply via email to