From b8f5abd85cacde1aebea5cbd54e7914dcb975748 Mon Sep 17 00:00:00 2001
From: Petr Cech <pcech@redhat.com>
Date: Wed, 24 Aug 2016 14:41:09 +0200
Subject: [PATCH] PROXY: Adding proxy_max_children option

The new option 'proxy_max_children' is applicable
in domain section. Default value is 10.

Resolves:
https://fedorahosted.org/sssd/ticket/3153
---
 src/confdb/confdb.h                       |  1 +
 src/config/SSSDConfig/__init__.py.in      |  3 +++
 src/config/cfg_rules.ini                  |  1 +
 src/config/etc/sssd.api.d/sssd-proxy.conf |  1 +
 src/man/sssd.conf.5.xml                   | 16 ++++++++++++++++
 src/providers/proxy/proxy_init.c          | 21 +++++++++++++++++++--
 6 files changed, 41 insertions(+), 2 deletions(-)

diff --git a/src/confdb/confdb.h b/src/confdb/confdb.h
index 401e5fbf7ed6bb9e8d7158dfab378c8159aa03db..9b5c7bc04bb8297842aa9a0ef50f239c50302757 100644
--- a/src/confdb/confdb.h
+++ b/src/confdb/confdb.h
@@ -218,6 +218,7 @@
 #define CONFDB_PROXY_LIBNAME "proxy_lib_name"
 #define CONFDB_PROXY_PAM_TARGET "proxy_pam_target"
 #define CONFDB_PROXY_FAST_ALIAS "proxy_fast_alias"
+#define CONFDB_PROXY_MAX_CHILDREN "proxy_max_children"
 
 /* Secrets Service */
 #define CONFDB_SEC_CONF_ENTRY "config/secrets"
diff --git a/src/config/SSSDConfig/__init__.py.in b/src/config/SSSDConfig/__init__.py.in
index 0191920f93ab9016508e08785c25dd043c180c0b..8ba006fdfe710fbfba82b40fe9b20461813ef3c7 100644
--- a/src/config/SSSDConfig/__init__.py.in
+++ b/src/config/SSSDConfig/__init__.py.in
@@ -428,6 +428,9 @@ option_strings = {
     'default_shell' : _('Default shell, /bin/bash'),
     'base_directory' : _('Base for home directories'),
 
+    # [provider/proxy]
+    'proxy_max_children' : _('The number of preforked proxy children.'),
+
     # [provider/proxy/id]
     'proxy_lib_name' : _('The name of the NSS library to use'),
     'proxy_fast_alias' : _('Whether to look up canonical group name from cache if possible'),
diff --git a/src/config/cfg_rules.ini b/src/config/cfg_rules.ini
index 5e248066bd554d2a654a764f406f6b33c4d66733..5213ce4c7e623899edd305c43137a1dbdd7aac7e 100644
--- a/src/config/cfg_rules.ini
+++ b/src/config/cfg_rules.ini
@@ -304,6 +304,7 @@ option = base_directory
 option = proxy_lib_name
 option = proxy_fast_alias
 option = proxy_pam_target
+option = proxy_max_children
 
 # simple access provider specific options
 option = simple_allow_users
diff --git a/src/config/etc/sssd.api.d/sssd-proxy.conf b/src/config/etc/sssd.api.d/sssd-proxy.conf
index 89a6503f9b84b7eab5fb3b0dd591dea905b43adb..09bf82affcb4263de3abbb67d1d484f6b01a1824 100644
--- a/src/config/etc/sssd.api.d/sssd-proxy.conf
+++ b/src/config/etc/sssd.api.d/sssd-proxy.conf
@@ -1,4 +1,5 @@
 [provider/proxy]
+proxy_max_children = int, None, false
 
 [provider/proxy/id]
 proxy_lib_name = str, None, true
diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml
index ae291e0fc8f2f9afabcdf32f18a5ec12252bbbbf..cd1d8c2c5995a8fe210f2c87da09c957a2f2c5fe 100644
--- a/src/man/sssd.conf.5.xml
+++ b/src/man/sssd.conf.5.xml
@@ -2464,6 +2464,22 @@ subdomain_inherit = ldap_purge_cache_timeout
                     </listitem>
                 </varlistentry>
 
+                <varlistentry>
+                    <term>proxy_max_children (integer)</term>
+                    <listitem>
+                        <para>
+                            This option specifies the number of pre-forked
+                            proxy children. It is useful for high-load SSSD
+                            environments where sssd may run out of available
+                            child slots, which would cause some issues due to
+                            the requests being queued.
+                        </para>
+                        <para>
+                            Default: 10
+                        </para>
+                    </listitem>
+                </varlistentry>
+
             </variablelist>
         </para>
 
diff --git a/src/providers/proxy/proxy_init.c b/src/providers/proxy/proxy_init.c
index 1edf4fd64e54f4f0df7a78a9e56eb232a1d3e948..9782ab9cf711d699eb473aad0f5754a7c514a0fc 100644
--- a/src/providers/proxy/proxy_init.c
+++ b/src/providers/proxy/proxy_init.c
@@ -29,6 +29,8 @@
 
 #define NSS_FN_NAME "_nss_%s_%s"
 
+#define OPT_MAX_CHILDREN_DEFAULT 10
+
 #define ERROR_INITGR "The '%s' library does not provides the " \
                          "_nss_XXX_initgroups_dyn function!\n" \
                          "initgroups will be slow as it will require " \
@@ -220,6 +222,7 @@ static errno_t proxy_init_auth_ctx(TALLOC_CTX *mem_ctx,
     struct proxy_auth_ctx *auth_ctx;
     errno_t ret;
     int hret;
+    int max_children;
 
     auth_ctx = talloc_zero(mem_ctx, struct proxy_auth_ctx);
     if (auth_ctx == NULL) {
@@ -241,8 +244,22 @@ static errno_t proxy_init_auth_ctx(TALLOC_CTX *mem_ctx,
     }
 
     /* Set up request hash table */
-    /* FIXME: get max_children from configuration file */
-    auth_ctx->max_children = 10;
+    ret = confdb_get_int(be_ctx->cdb, be_ctx->conf_path,
+                         CONFDB_PROXY_MAX_CHILDREN,
+                         OPT_MAX_CHILDREN_DEFAULT,
+                         &max_children);
+    if (ret != EOK) {
+        DEBUG(SSSDBG_CRIT_FAILURE, "Unable to read confdb [%d]: %s\n",
+                                   ret, sss_strerror(ret));
+        goto done;
+    }
+    if (max_children < 1) {
+        DEBUG(SSSDBG_CRIT_FAILURE, "Option %s must be bigger then 1\n",
+                                   CONFDB_PROXY_MAX_CHILDREN);
+        ret = EINVAL;
+        goto done;
+    }
+    auth_ctx->max_children = max_children;
 
     hret = hash_create(auth_ctx->max_children * 2, &auth_ctx->request_table,
                        NULL, NULL);
-- 
2.7.4

