URL: https://github.com/SSSD/sssd/pull/999
Author: alexey-tikhonov
 Title: #999: Mem-cache fixes/improvements
Action: synchronized

To pull the PR as Git branch:
git remote add ghsssd https://github.com/SSSD/sssd
git fetch ghsssd pull/999/head:pr999
git checkout pr999
From f4e03585ff1d651c25db33b61032a9f3d81a1a87 Mon Sep 17 00:00:00 2001
From: Alexey Tikhonov <atikh...@redhat.com>
Date: Tue, 3 Mar 2020 18:44:11 +0100
Subject: [PATCH 1/7] mem-cache: sizes of free and data tables were made
 consistent

Since size of "free table" didn't account for SSS_AVG_*_PAYLOAD factor
only small fraction of "data table" was actually used.
SSS_AVG_*_PAYLOAD differentiation for different payload types only
affected size of hash table and was removed as unjustified.

Resolves: https://pagure.io/SSSD/sssd/issue/4160
---
 src/responder/nss/nsssrv.c            | 22 +++++++++++-------
 src/responder/nss/nsssrv_mmap_cache.c | 33 +++++++--------------------
 src/responder/nss/nsssrv_mmap_cache.h |  2 --
 src/util/mmap_cache.h                 |  3 ---
 4 files changed, 22 insertions(+), 38 deletions(-)

diff --git a/src/responder/nss/nsssrv.c b/src/responder/nss/nsssrv.c
index 6ef0db401d..0677de6227 100644
--- a/src/responder/nss/nsssrv.c
+++ b/src/responder/nss/nsssrv.c
@@ -83,10 +83,9 @@ nss_clear_memcache(TALLOC_CTX *mem_ctx,
         return ret;
     }
 
-    /* TODO: read cache sizes from configuration */
     DEBUG(SSSDBG_TRACE_FUNC, "Clearing memory caches.\n");
     ret = sss_mmap_cache_reinit(nctx, nctx->mc_uid, nctx->mc_gid,
-                                SSS_MC_CACHE_ELEMENTS,
+                                -1, /* keep current size */
                                 (time_t) memcache_timeout,
                                 &nctx->pwd_mc_ctx);
     if (ret != EOK) {
@@ -96,7 +95,7 @@ nss_clear_memcache(TALLOC_CTX *mem_ctx,
     }
 
     ret = sss_mmap_cache_reinit(nctx, nctx->mc_uid, nctx->mc_gid,
-                                SSS_MC_CACHE_ELEMENTS,
+                                -1, /* keep current size */
                                 (time_t) memcache_timeout,
                                 &nctx->grp_mc_ctx);
     if (ret != EOK) {
@@ -106,7 +105,7 @@ nss_clear_memcache(TALLOC_CTX *mem_ctx,
     }
 
     ret = sss_mmap_cache_reinit(nctx, nctx->mc_uid, nctx->mc_gid,
-                                SSS_MC_CACHE_ELEMENTS,
+                                -1, /* keep current size */
                                 (time_t)memcache_timeout,
                                 &nctx->initgr_mc_ctx);
     if (ret != EOK) {
@@ -210,6 +209,11 @@ static int nss_get_config(struct nss_ctx *nctx,
 
 static int setup_memcaches(struct nss_ctx *nctx)
 {
+    /* TODO: read cache sizes from configuration */
+    static const size_t SSS_MC_CACHE_PASSWD_SLOTS    = 200000;  /*  8mb */
+    static const size_t SSS_MC_CACHE_GROUP_SLOTS     = 150000;  /*  6mb */
+    static const size_t SSS_MC_CACHE_INITGROUP_SLOTS = 250000;  /* 10mb */
+
     int ret;
     int memcache_timeout;
 
@@ -239,11 +243,11 @@ static int setup_memcaches(struct nss_ctx *nctx)
         return EOK;
     }
 
-    /* TODO: read cache sizes from configuration */
     ret = sss_mmap_cache_init(nctx, "passwd",
                               nctx->mc_uid, nctx->mc_gid,
                               SSS_MC_PASSWD,
-                              SSS_MC_CACHE_ELEMENTS, (time_t)memcache_timeout,
+                              SSS_MC_CACHE_PASSWD_SLOTS,
+                              (time_t)memcache_timeout,
                               &nctx->pwd_mc_ctx);
     if (ret) {
         DEBUG(SSSDBG_CRIT_FAILURE, "passwd mmap cache is DISABLED\n");
@@ -252,7 +256,8 @@ static int setup_memcaches(struct nss_ctx *nctx)
     ret = sss_mmap_cache_init(nctx, "group",
                               nctx->mc_uid, nctx->mc_gid,
                               SSS_MC_GROUP,
-                              SSS_MC_CACHE_ELEMENTS, (time_t)memcache_timeout,
+                              SSS_MC_CACHE_GROUP_SLOTS,
+                              (time_t)memcache_timeout,
                               &nctx->grp_mc_ctx);
     if (ret) {
         DEBUG(SSSDBG_CRIT_FAILURE, "group mmap cache is DISABLED\n");
@@ -261,7 +266,8 @@ static int setup_memcaches(struct nss_ctx *nctx)
     ret = sss_mmap_cache_init(nctx, "initgroups",
                               nctx->mc_uid, nctx->mc_gid,
                               SSS_MC_INITGROUPS,
-                              SSS_MC_CACHE_ELEMENTS, (time_t)memcache_timeout,
+                              SSS_MC_CACHE_INITGROUP_SLOTS,
+                              (time_t)memcache_timeout,
                               &nctx->initgr_mc_ctx);
     if (ret) {
         DEBUG(SSSDBG_CRIT_FAILURE, "initgroups mmap cache is DISABLED\n");
diff --git a/src/responder/nss/nsssrv_mmap_cache.c b/src/responder/nss/nsssrv_mmap_cache.c
index 493b74e386..af7e865f32 100644
--- a/src/responder/nss/nsssrv_mmap_cache.c
+++ b/src/responder/nss/nsssrv_mmap_cache.c
@@ -28,13 +28,6 @@
 #include "responder/nss/nss_private.h"
 #include "responder/nss/nsssrv_mmap_cache.h"
 
-/* arbitrary (avg of my /etc/passwd) */
-#define SSS_AVG_PASSWD_PAYLOAD (MC_SLOT_SIZE * 4)
-/* short group name and no gids (private user group */
-#define SSS_AVG_GROUP_PAYLOAD (MC_SLOT_SIZE * 3)
-/* average place for 40 supplementary groups + 2 names */
-#define SSS_AVG_INITGROUP_PAYLOAD (MC_SLOT_SIZE * 5)
-
 #define MC_NEXT_BARRIER(val) ((((val) + 1) & 0x00ffffff) | 0xf0000000)
 
 #define MC_RAISE_BARRIER(m) do { \
@@ -1254,24 +1247,14 @@ errno_t sss_mmap_cache_init(TALLOC_CTX *mem_ctx, const char *name,
                             enum sss_mc_type type, size_t n_elem,
                             time_t timeout, struct sss_mc_ctx **mcc)
 {
+    /* sss_mc_header alone occupies whole slot,
+     * so each entry takes 2 slots at the very least
+     */
+    static const int PAYLOAD_FACTOR = 2;
+
     struct sss_mc_ctx *mc_ctx = NULL;
-    int payload;
     int ret, dret;
 
-    switch (type) {
-    case SSS_MC_PASSWD:
-        payload = SSS_AVG_PASSWD_PAYLOAD;
-        break;
-    case SSS_MC_GROUP:
-        payload = SSS_AVG_GROUP_PAYLOAD;
-        break;
-    case SSS_MC_INITGROUPS:
-        payload = SSS_AVG_INITGROUP_PAYLOAD;
-        break;
-    default:
-        return EINVAL;
-    }
-
     mc_ctx = talloc_zero(mem_ctx, struct sss_mc_ctx);
     if (!mc_ctx) {
         return ENOMEM;
@@ -1306,9 +1289,9 @@ errno_t sss_mmap_cache_init(TALLOC_CTX *mem_ctx, const char *name,
 
     /* hash table is double the size because it will store both forward and
      * reverse keys (name/uid, name/gid, ..) */
-    mc_ctx->ht_size = MC_HT_SIZE(n_elem * 2);
-    mc_ctx->dt_size = MC_DT_SIZE(n_elem, payload);
-    mc_ctx->ft_size = MC_FT_SIZE(n_elem);
+    mc_ctx->ht_size = MC_HT_SIZE(2 * n_elem / PAYLOAD_FACTOR);
+    mc_ctx->dt_size = n_elem * MC_SLOT_SIZE;
+    mc_ctx->ft_size = n_elem / 8; /* 1 bit per slot */
     mc_ctx->mmap_size = MC_HEADER_SIZE +
                         MC_ALIGN64(mc_ctx->dt_size) +
                         MC_ALIGN64(mc_ctx->ft_size) +
diff --git a/src/responder/nss/nsssrv_mmap_cache.h b/src/responder/nss/nsssrv_mmap_cache.h
index e062579499..c40af2fb4a 100644
--- a/src/responder/nss/nsssrv_mmap_cache.h
+++ b/src/responder/nss/nsssrv_mmap_cache.h
@@ -22,8 +22,6 @@
 #ifndef _NSSSRV_MMAP_CACHE_H_
 #define _NSSSRV_MMAP_CACHE_H_
 
-#define SSS_MC_CACHE_ELEMENTS 50000
-
 struct sss_mc_ctx;
 
 enum sss_mc_type {
diff --git a/src/util/mmap_cache.h b/src/util/mmap_cache.h
index 63e096027f..d3d92bc982 100644
--- a/src/util/mmap_cache.h
+++ b/src/util/mmap_cache.h
@@ -40,9 +40,6 @@ typedef uint32_t rel_ptr_t;
 
 #define MC_HT_SIZE(elems) ( (elems) * MC_32 )
 #define MC_HT_ELEMS(size) ( (size) / MC_32 )
-#define MC_DT_SIZE(elems, payload) ( (elems) * (payload) )
-#define MC_FT_SIZE(elems) ( (elems) / 8 )
-/* ^^ 8 bits per byte so we need just elems/8 bytes to represent all blocks */
 
 #define MC_PTR_ADD(ptr, bytes) (void *)((uint8_t *)(ptr) + (bytes))
 #define MC_PTR_DIFF(ptr, base) ((uint8_t *)(ptr) - (uint8_t *)(base))

From fee55f17b3ceb7568facb774e6a46554eee9b031 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michal=20=C5=BDidek?= <mzi...@redhat.com>
Date: Wed, 4 Mar 2020 16:26:18 +0100
Subject: [PATCH 2/7] NSS: make memcache size configurable

Added options to configure memcache size:
memcache_size_passwd
memcache_size_group
memcache_size_initgroups

Related:
https://pagure.io/SSSD/sssd/issue/3552
---
 src/confdb/confdb.h                  |   3 +
 src/config/SSSDConfig/sssdoptions.py |   3 +
 src/config/cfg_rules.ini             |   3 +
 src/man/sssd.conf.5.xml              |  78 +++++++++
 src/responder/nss/nsssrv.c           | 104 ++++++++----
 src/tests/intg/test_memory_cache.py  | 236 +++++++++++++++++++++++++++
 6 files changed, 398 insertions(+), 29 deletions(-)

diff --git a/src/confdb/confdb.h b/src/confdb/confdb.h
index ee902500ea..cb3dd1c890 100644
--- a/src/confdb/confdb.h
+++ b/src/confdb/confdb.h
@@ -113,6 +113,9 @@
 #define CONFDB_NSS_SHELL_FALLBACK "shell_fallback"
 #define CONFDB_NSS_DEFAULT_SHELL "default_shell"
 #define CONFDB_MEMCACHE_TIMEOUT "memcache_timeout"
+#define CONFDB_NSS_MEMCACHE_SIZE_PASSWD "memcache_size_passwd"
+#define CONFDB_NSS_MEMCACHE_SIZE_GROUP "memcache_size_group"
+#define CONFDB_NSS_MEMCACHE_SIZE_INITGROUPS "memcache_size_initgroups"
 #define CONFDB_NSS_HOMEDIR_SUBSTRING "homedir_substring"
 #define CONFDB_DEFAULT_HOMEDIR_SUBSTRING "/home"
 
diff --git a/src/config/SSSDConfig/sssdoptions.py b/src/config/SSSDConfig/sssdoptions.py
index 51375d0657..14a2d04c03 100644
--- a/src/config/SSSDConfig/sssdoptions.py
+++ b/src/config/SSSDConfig/sssdoptions.py
@@ -72,6 +72,9 @@ def __init__(self):
         'shell_fallback': _('If a shell stored in central directory is allowed but not available, use this fallback'),
         'default_shell': _('Shell to use if the provider does not list one'),
         'memcache_timeout': _('How long will be in-memory cache records valid'),
+        'memcache_size_passwd': _('Number of slots in fast in-memory cache for passwd requests'),
+        'memcache_size_group': _('Number of slots in fast in-memory cache for group requests'),
+        'memcache_size_initgroups': _('Number of slots in fast in-memory cache for initgroups requests'),
         'homedir_substring': _('The value of this option will be used in the expansion of the override_homedir option '
                                'if the template contains the format string %H.'),
         'get_domains_timeout': _('Specifies time in seconds for which the list of subdomains will be considered '
diff --git a/src/config/cfg_rules.ini b/src/config/cfg_rules.ini
index 66df64aef2..88aff7dd3c 100644
--- a/src/config/cfg_rules.ini
+++ b/src/config/cfg_rules.ini
@@ -92,6 +92,9 @@ option = shell_fallback
 option = default_shell
 option = get_domains_timeout
 option = memcache_timeout
+option = memcache_size_passwd
+option = memcache_size_group
+option = memcache_size_initgroups
 
 [rule/allowed_pam_options]
 validator = ini_allowed_options
diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml
index a2567f5acb..e41d061dc6 100644
--- a/src/man/sssd.conf.5.xml
+++ b/src/man/sssd.conf.5.xml
@@ -1100,6 +1100,84 @@ fallback_homedir = /home/%u
                         </para>
                     </listitem>
                 </varlistentry>
+                <varlistentry>
+                    <term>memcache_size_passwd (integer)</term>
+                    <listitem>
+                        <para>
+                            Number of slots allocated inside fast in-memory
+                            cache for passwd requests. Note that one entry
+                            in fast in-memory cache can occupy more than one slot.
+                            Setting the size to 0 will disable the passwd in-memory
+                            cache.
+                        </para>
+                        <para>
+                            Default: 200000
+                        </para>
+                        <para>
+                            WARNING: Disabled or too small in-memory cache can
+                            have significant negative impact on SSSD's
+                            performance.
+                        </para>
+                        <para>
+                            NOTE: If the environment variable
+                            SSS_NSS_USE_MEMCACHE is set to "NO", client
+                            applications will not use the fast in-memory
+                            cache.
+                        </para>
+                    </listitem>
+                </varlistentry>
+                <varlistentry>
+                    <term>memcache_size_group (integer)</term>
+                    <listitem>
+                        <para>
+                            Number of slots allocated inside fast in-memory
+                            cache for group requests. Note that one entry
+                            in fast in-memory cache can occupy more than one
+                            slot. Setting the size to 0 will disable the group
+                            in-memory cache.
+                        </para>
+                        <para>
+                            Default: 150000
+                        </para>
+                        <para>
+                            WARNING: Disabled or too small in-memory cache can
+                            have significant negative impact on SSSD's
+                            performance.
+                        </para>
+                        <para>
+                            NOTE: If the environment variable
+                            SSS_NSS_USE_MEMCACHE is set to "NO", client
+                            applications will not use the fast in-memory
+                            cache.
+                        </para>
+                    </listitem>
+                </varlistentry>
+                <varlistentry>
+                    <term>memcache_size_initgroups (integer)</term>
+                    <listitem>
+                        <para>
+                            Number of slots allocated inside fast in-memory
+                            cache for initgroups requests. Note that one entry
+                            in fast in-memory cache can occupy more than one
+                            slot. Setting the size to 0 will disable the
+                            initgroups in-memory cache.
+                        </para>
+                        <para>
+                            Default: 250000
+                        </para>
+                        <para>
+                            WARNING: Disabled or too small in-memory cache can
+                            have significant negative impact on SSSD's
+                            performance.
+                        </para>
+                        <para>
+                            NOTE: If the environment variable
+                            SSS_NSS_USE_MEMCACHE is set to "NO", client
+                            applications will not use the fast in-memory
+                            cache.
+                        </para>
+                    </listitem>
+                </varlistentry>
                 <varlistentry>
                     <term>user_attributes (string)</term>
                     <listitem>
diff --git a/src/responder/nss/nsssrv.c b/src/responder/nss/nsssrv.c
index 0677de6227..2f72cef1b6 100644
--- a/src/responder/nss/nsssrv.c
+++ b/src/responder/nss/nsssrv.c
@@ -209,13 +209,16 @@ static int nss_get_config(struct nss_ctx *nctx,
 
 static int setup_memcaches(struct nss_ctx *nctx)
 {
-    /* TODO: read cache sizes from configuration */
+    /* Default memcache sizes */
     static const size_t SSS_MC_CACHE_PASSWD_SLOTS    = 200000;  /*  8mb */
     static const size_t SSS_MC_CACHE_GROUP_SLOTS     = 150000;  /*  6mb */
     static const size_t SSS_MC_CACHE_INITGROUP_SLOTS = 250000;  /* 10mb */
 
     int ret;
     int memcache_timeout;
+    int mc_size_passwd;
+    int mc_size_group;
+    int mc_size_initgroups;
 
     /* Remove the CLEAR_MC_FLAG file if exists. */
     ret = unlink(SSS_NSS_MCACHE_DIR"/"CLEAR_MC_FLAG);
@@ -243,34 +246,77 @@ static int setup_memcaches(struct nss_ctx *nctx)
         return EOK;
     }
 
-    ret = sss_mmap_cache_init(nctx, "passwd",
-                              nctx->mc_uid, nctx->mc_gid,
-                              SSS_MC_PASSWD,
-                              SSS_MC_CACHE_PASSWD_SLOTS,
-                              (time_t)memcache_timeout,
-                              &nctx->pwd_mc_ctx);
-    if (ret) {
-        DEBUG(SSSDBG_CRIT_FAILURE, "passwd mmap cache is DISABLED\n");
-    }
-
-    ret = sss_mmap_cache_init(nctx, "group",
-                              nctx->mc_uid, nctx->mc_gid,
-                              SSS_MC_GROUP,
-                              SSS_MC_CACHE_GROUP_SLOTS,
-                              (time_t)memcache_timeout,
-                              &nctx->grp_mc_ctx);
-    if (ret) {
-        DEBUG(SSSDBG_CRIT_FAILURE, "group mmap cache is DISABLED\n");
-    }
-
-    ret = sss_mmap_cache_init(nctx, "initgroups",
-                              nctx->mc_uid, nctx->mc_gid,
-                              SSS_MC_INITGROUPS,
-                              SSS_MC_CACHE_INITGROUP_SLOTS,
-                              (time_t)memcache_timeout,
-                              &nctx->initgr_mc_ctx);
-    if (ret) {
-        DEBUG(SSSDBG_CRIT_FAILURE, "initgroups mmap cache is DISABLED\n");
+    /* Get all memcache sizes from confdb (pwd, grp, initgr) */
+
+    ret = confdb_get_int(nctx->rctx->cdb,
+                         CONFDB_NSS_CONF_ENTRY,
+                         CONFDB_NSS_MEMCACHE_SIZE_PASSWD,
+                         SSS_MC_CACHE_PASSWD_SLOTS,
+                         &mc_size_passwd);
+    if (ret != EOK) {
+        DEBUG(SSSDBG_FATAL_FAILURE,
+              "Failed to get 'memcache_size_passwd' option from confdb.\n");
+        return ret;
+    }
+
+    ret = confdb_get_int(nctx->rctx->cdb,
+                         CONFDB_NSS_CONF_ENTRY,
+                         CONFDB_NSS_MEMCACHE_SIZE_GROUP,
+                         SSS_MC_CACHE_GROUP_SLOTS,
+                         &mc_size_group);
+    if (ret != EOK) {
+        DEBUG(SSSDBG_FATAL_FAILURE,
+              "Failed to get 'memcache_size_group' option from confdb.\n");
+        return ret;
+    }
+
+    ret = confdb_get_int(nctx->rctx->cdb,
+                         CONFDB_NSS_CONF_ENTRY,
+                         CONFDB_NSS_MEMCACHE_SIZE_INITGROUPS,
+                         SSS_MC_CACHE_INITGROUP_SLOTS,
+                         &mc_size_initgroups);
+    if (ret != EOK) {
+        DEBUG(SSSDBG_FATAL_FAILURE,
+              "Failed to get 'memcache_size_nitgroups' option from confdb.\n");
+        return ret;
+    }
+
+    /* Initialize the fast in-memory caches if they were not disabled */
+
+    if (mc_size_passwd != 0) {
+        ret = sss_mmap_cache_init(nctx, "passwd",
+                                  nctx->mc_uid, nctx->mc_gid,
+                                  SSS_MC_PASSWD,
+                                  mc_size_passwd,
+                                  (time_t)memcache_timeout,
+                                  &nctx->pwd_mc_ctx);
+        if (ret) {
+            DEBUG(SSSDBG_CRIT_FAILURE, "passwd mmap cache is DISABLED\n");
+        }
+    }
+
+    if (mc_size_group != 0) {
+        ret = sss_mmap_cache_init(nctx, "group",
+                                  nctx->mc_uid, nctx->mc_gid,
+                                  SSS_MC_GROUP,
+                                  mc_size_group,
+                                  (time_t)memcache_timeout,
+                                  &nctx->grp_mc_ctx);
+        if (ret) {
+            DEBUG(SSSDBG_CRIT_FAILURE, "group mmap cache is DISABLED\n");
+        }
+    }
+
+    if (mc_size_initgroups != 0) {
+        ret = sss_mmap_cache_init(nctx, "initgroups",
+                                  nctx->mc_uid, nctx->mc_gid,
+                                  SSS_MC_INITGROUPS,
+                                  mc_size_initgroups,
+                                  (time_t)memcache_timeout,
+                                  &nctx->initgr_mc_ctx);
+        if (ret) {
+            DEBUG(SSSDBG_CRIT_FAILURE, "initgroups mmap cache is DISABLED\n");
+        }
     }
 
     return EOK;
diff --git a/src/tests/intg/test_memory_cache.py b/src/tests/intg/test_memory_cache.py
index 8d66a37ca7..e7796eb8eb 100644
--- a/src/tests/intg/test_memory_cache.py
+++ b/src/tests/intg/test_memory_cache.py
@@ -135,6 +135,112 @@ def load_data_to_ldap(request, ldap_conn):
     create_ldap_fixture(request, ldap_conn, ent_list)
 
 
+@pytest.fixture
+def disable_memcache_rfc2307(request, ldap_conn):
+    load_data_to_ldap(request, ldap_conn)
+
+    conf = unindent("""\
+        [sssd]
+        domains             = LDAP
+        services            = nss
+
+        [nss]
+        memcache_size_group = 0
+        memcache_size_passwd = 0
+        memcache_size_initgroups = 0
+
+        [domain/LDAP]
+        ldap_auth_disable_tls_never_use_in_production = true
+        ldap_schema         = rfc2307
+        id_provider         = ldap
+        auth_provider       = ldap
+        sudo_provider       = ldap
+        ldap_uri            = {ldap_conn.ds_inst.ldap_url}
+        ldap_search_base    = {ldap_conn.ds_inst.base_dn}
+    """).format(**locals())
+    create_conf_fixture(request, conf)
+    create_sssd_fixture(request)
+    return None
+
+
+@pytest.fixture
+def disable_pwd_mc_rfc2307(request, ldap_conn):
+    load_data_to_ldap(request, ldap_conn)
+
+    conf = unindent("""\
+        [sssd]
+        domains             = LDAP
+        services            = nss
+
+        [nss]
+        memcache_size_passwd = 0
+
+        [domain/LDAP]
+        ldap_auth_disable_tls_never_use_in_production = true
+        ldap_schema         = rfc2307
+        id_provider         = ldap
+        auth_provider       = ldap
+        sudo_provider       = ldap
+        ldap_uri            = {ldap_conn.ds_inst.ldap_url}
+        ldap_search_base    = {ldap_conn.ds_inst.base_dn}
+    """).format(**locals())
+    create_conf_fixture(request, conf)
+    create_sssd_fixture(request)
+    return None
+
+
+@pytest.fixture
+def disable_grp_mc_rfc2307(request, ldap_conn):
+    load_data_to_ldap(request, ldap_conn)
+
+    conf = unindent("""\
+        [sssd]
+        domains             = LDAP
+        services            = nss
+
+        [nss]
+        memcache_size_group = 0
+
+        [domain/LDAP]
+        ldap_auth_disable_tls_never_use_in_production = true
+        ldap_schema         = rfc2307
+        id_provider         = ldap
+        auth_provider       = ldap
+        sudo_provider       = ldap
+        ldap_uri            = {ldap_conn.ds_inst.ldap_url}
+        ldap_search_base    = {ldap_conn.ds_inst.base_dn}
+    """).format(**locals())
+    create_conf_fixture(request, conf)
+    create_sssd_fixture(request)
+    return None
+
+
+@pytest.fixture
+def disable_initgr_mc_rfc2307(request, ldap_conn):
+    load_data_to_ldap(request, ldap_conn)
+
+    conf = unindent("""\
+        [sssd]
+        domains             = LDAP
+        services            = nss
+
+        [nss]
+        memcache_size_initgroups = 0
+
+        [domain/LDAP]
+        ldap_auth_disable_tls_never_use_in_production = true
+        ldap_schema         = rfc2307
+        id_provider         = ldap
+        auth_provider       = ldap
+        sudo_provider       = ldap
+        ldap_uri            = {ldap_conn.ds_inst.ldap_url}
+        ldap_search_base    = {ldap_conn.ds_inst.base_dn}
+    """).format(**locals())
+    create_conf_fixture(request, conf)
+    create_sssd_fixture(request)
+    return None
+
+
 @pytest.fixture
 def sanity_rfc2307(request, ldap_conn):
     load_data_to_ldap(request, ldap_conn)
@@ -354,6 +460,19 @@ def test_getgrnam_simple_with_mc(ldap_conn, sanity_rfc2307):
     test_getgrnam_simple(ldap_conn, sanity_rfc2307)
 
 
+def test_getgrnam_simple_disabled_pwd_mc(ldap_conn, disable_pwd_mc_rfc2307):
+    test_getgrnam_simple(ldap_conn, disable_pwd_mc_rfc2307)
+    stop_sssd()
+    test_getgrnam_simple(ldap_conn, disable_pwd_mc_rfc2307)
+
+
+def test_getgrnam_simple_disabled_intitgr_mc(ldap_conn,
+                                             disable_initgr_mc_rfc2307):
+    test_getgrnam_simple(ldap_conn, disable_initgr_mc_rfc2307)
+    stop_sssd()
+    test_getgrnam_simple(ldap_conn, disable_initgr_mc_rfc2307)
+
+
 def test_getgrnam_membership(ldap_conn, sanity_rfc2307):
     ent.assert_group_by_name(
         "group1",
@@ -919,3 +1038,120 @@ def test_mc_zero_timeout(ldap_conn, zero_timeout_rfc2307):
         grp.getgrnam('group1')
     with pytest.raises(KeyError):
         grp.getgrgid(2001)
+
+
+def test_disabled_mc(ldap_conn, disable_memcache_rfc2307):
+    ent.assert_passwd_by_name(
+        'user1',
+        dict(name='user1', passwd='*', uid=1001, gid=2001,
+             gecos='1001', shell='/bin/bash'))
+    ent.assert_passwd_by_uid(
+        1001,
+        dict(name='user1', passwd='*', uid=1001, gid=2001,
+             gecos='1001', shell='/bin/bash'))
+
+    ent.assert_group_by_name("group1", dict(name="group1", gid=2001))
+    ent.assert_group_by_gid(2001, dict(name="group1", gid=2001))
+
+    assert_user_gids_equal('user1', [2000, 2001])
+
+    stop_sssd()
+
+    # sssd is stopped and the memory cache is disabled;
+    # so pytest should not be able to find anything
+    with pytest.raises(KeyError):
+        pwd.getpwnam('user1')
+    with pytest.raises(KeyError):
+        pwd.getpwuid(1001)
+
+    with pytest.raises(KeyError):
+        grp.getgrnam('group1')
+    with pytest.raises(KeyError):
+        grp.getgrgid(2001)
+
+    with pytest.raises(KeyError):
+        (res, errno, gids) = sssd_id.get_user_gids('user1')
+
+
+def test_disabled_passwd_mc(ldap_conn, disable_pwd_mc_rfc2307):
+    ent.assert_passwd_by_name(
+        'user1',
+        dict(name='user1', passwd='*', uid=1001, gid=2001,
+             gecos='1001', shell='/bin/bash'))
+    ent.assert_passwd_by_uid(
+        1001,
+        dict(name='user1', passwd='*', uid=1001, gid=2001,
+             gecos='1001', shell='/bin/bash'))
+
+    assert_user_gids_equal('user1', [2000, 2001])
+
+    stop_sssd()
+
+    # passwd cache is disabled
+    with pytest.raises(KeyError):
+        pwd.getpwnam('user1')
+    with pytest.raises(KeyError):
+        pwd.getpwuid(1001)
+
+    # Initgroups looks up the user first, hence KeyError from the
+    # passwd database even if the initgroups cache is active.
+    with pytest.raises(KeyError):
+        (res, errno, gids) = sssd_id.get_user_gids('user1')
+
+
+def test_disabled_group_mc(ldap_conn, disable_grp_mc_rfc2307):
+    ent.assert_passwd_by_name(
+        'user1',
+        dict(name='user1', passwd='*', uid=1001, gid=2001,
+             gecos='1001', shell='/bin/bash'))
+    ent.assert_passwd_by_uid(
+        1001,
+        dict(name='user1', passwd='*', uid=1001, gid=2001,
+             gecos='1001', shell='/bin/bash'))
+
+    ent.assert_group_by_name("group1", dict(name="group1", gid=2001))
+    ent.assert_group_by_gid(2001, dict(name="group1", gid=2001))
+
+    assert_user_gids_equal('user1', [2000, 2001])
+
+    stop_sssd()
+
+    # group cache is disabled, other caches should work
+    ent.assert_passwd_by_name(
+        'user1',
+        dict(name='user1', passwd='*', uid=1001, gid=2001,
+             gecos='1001', shell='/bin/bash'))
+    ent.assert_passwd_by_uid(
+        1001,
+        dict(name='user1', passwd='*', uid=1001, gid=2001,
+             gecos='1001', shell='/bin/bash'))
+
+    with pytest.raises(KeyError):
+        grp.getgrnam('group1')
+    with pytest.raises(KeyError):
+        grp.getgrgid(2001)
+
+    assert_user_gids_equal('user1', [2000, 2001])
+
+
+def test_disabled_initgr_mc(ldap_conn, disable_initgr_mc_rfc2307):
+    # Even if initgroups is disabled, passwd should work
+    ent.assert_passwd_by_name(
+        'user1',
+        dict(name='user1', passwd='*', uid=1001, gid=2001,
+             gecos='1001', shell='/bin/bash'))
+    ent.assert_passwd_by_uid(
+        1001,
+        dict(name='user1', passwd='*', uid=1001, gid=2001,
+             gecos='1001', shell='/bin/bash'))
+
+    stop_sssd()
+
+    ent.assert_passwd_by_name(
+        'user1',
+        dict(name='user1', passwd='*', uid=1001, gid=2001,
+             gecos='1001', shell='/bin/bash'))
+    ent.assert_passwd_by_uid(
+        1001,
+        dict(name='user1', passwd='*', uid=1001, gid=2001,
+             gecos='1001', shell='/bin/bash'))

From 6231df2e1682f05e083ff3ceab59370794a14cc4 Mon Sep 17 00:00:00 2001
From: Alexey Tikhonov <atikh...@redhat.com>
Date: Wed, 4 Mar 2020 21:09:33 +0100
Subject: [PATCH 3/7] NSS: avoid excessive log messages

 - do not log error message if mem-cache was disabled explicitly
 - increase message severity in case of fail to store entry in mem-cache
---
 src/responder/nss/nss_protocol_grent.c | 12 +++++++-----
 src/responder/nss/nss_protocol_pwent.c |  7 ++++---
 2 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/src/responder/nss/nss_protocol_grent.c b/src/responder/nss/nss_protocol_grent.c
index 2367d9ecd9..efe9cce25e 100644
--- a/src/responder/nss/nss_protocol_grent.c
+++ b/src/responder/nss/nss_protocol_grent.c
@@ -275,16 +275,17 @@ nss_protocol_fill_grent(struct nss_ctx *nss_ctx,
         num_results++;
 
         /* Do not store entry in memory cache during enumeration or when
-         * requested. */
+         * requested or if cache explicitly disabled. */
         if (!cmd_ctx->enumeration
-                && (cmd_ctx->flags & SSS_NSS_EX_FLAG_INVALIDATE_CACHE) == 0) {
+                && ((cmd_ctx->flags & SSS_NSS_EX_FLAG_INVALIDATE_CACHE) == 0)
+                && (nss_ctx->grp_mc_ctx != NULL)) {
             members = (char *)&body[rp_members];
             members_size = body_len - rp_members;
             ret = sss_mmap_cache_gr_store(&nss_ctx->grp_mc_ctx, name, &pwfield,
                                           gid, num_members, members,
                                           members_size);
             if (ret != EOK) {
-                DEBUG(SSSDBG_MINOR_FAILURE,
+                DEBUG(SSSDBG_OP_FAILURE,
                       "Failed to store group %s (%s) in mem-cache [%d]: %s!\n",
                       name->str, result->domain->name, ret, sss_strerror(ret));
             }
@@ -406,7 +407,8 @@ nss_protocol_fill_initgr(struct nss_ctx *nss_ctx,
     }
 
     if (nss_ctx->initgr_mc_ctx
-                && (cmd_ctx->flags & SSS_NSS_EX_FLAG_INVALIDATE_CACHE) == 0) {
+                && ((cmd_ctx->flags & SSS_NSS_EX_FLAG_INVALIDATE_CACHE) == 0)
+                && (nss_ctx->initgr_mc_ctx != NULL)) {
         to_sized_string(&rawname, cmd_ctx->rawname);
         to_sized_string(&unique_name, result->lookup_name);
 
@@ -414,7 +416,7 @@ nss_protocol_fill_initgr(struct nss_ctx *nss_ctx,
                                           &unique_name, num_results,
                                           body + 2 * sizeof(uint32_t));
         if (ret != EOK) {
-            DEBUG(SSSDBG_MINOR_FAILURE,
+            DEBUG(SSSDBG_OP_FAILURE,
                   "Failed to store initgroups %s (%s) in mem-cache [%d]: %s!\n",
                   rawname.str, domain->name, ret, sss_strerror(ret));
             sss_packet_set_size(packet, 0);
diff --git a/src/responder/nss/nss_protocol_pwent.c b/src/responder/nss/nss_protocol_pwent.c
index 86fa4ec465..d32c542581 100644
--- a/src/responder/nss/nss_protocol_pwent.c
+++ b/src/responder/nss/nss_protocol_pwent.c
@@ -301,13 +301,14 @@ nss_protocol_fill_pwent(struct nss_ctx *nss_ctx,
         num_results++;
 
         /* Do not store entry in memory cache during enumeration or when
-         * requested. */
+         * requested or if cache explicitly disabled. */
         if (!cmd_ctx->enumeration
-                && (cmd_ctx->flags & SSS_NSS_EX_FLAG_INVALIDATE_CACHE) == 0) {
+                && ((cmd_ctx->flags & SSS_NSS_EX_FLAG_INVALIDATE_CACHE) == 0)
+                && (nss_ctx->pwd_mc_ctx != NULL)) {
             ret = sss_mmap_cache_pw_store(&nss_ctx->pwd_mc_ctx, name, &pwfield,
                                           uid, gid, &gecos, &homedir, &shell);
             if (ret != EOK) {
-                DEBUG(SSSDBG_MINOR_FAILURE,
+                DEBUG(SSSDBG_OP_FAILURE,
                       "Failed to store user %s (%s) in mmap cache [%d]: %s!\n",
                       name->str, result->domain->name, ret, sss_strerror(ret));
             }

From 987e35a0ad24ab78952c4dacb2a0e16ec0d988dd Mon Sep 17 00:00:00 2001
From: Alexey Tikhonov <atikh...@redhat.com>
Date: Wed, 4 Mar 2020 22:13:52 +0100
Subject: [PATCH 4/7] NSS: enhanced debug during mem-cache initialization

---
 src/responder/nss/nsssrv.c | 39 ++++++++++++++++++++++++++++++++------
 1 file changed, 33 insertions(+), 6 deletions(-)

diff --git a/src/responder/nss/nsssrv.c b/src/responder/nss/nsssrv.c
index 2f72cef1b6..5f8d9e3478 100644
--- a/src/responder/nss/nsssrv.c
+++ b/src/responder/nss/nsssrv.c
@@ -255,7 +255,8 @@ static int setup_memcaches(struct nss_ctx *nctx)
                          &mc_size_passwd);
     if (ret != EOK) {
         DEBUG(SSSDBG_FATAL_FAILURE,
-              "Failed to get 'memcache_size_passwd' option from confdb.\n");
+              "Failed to get '"CONFDB_NSS_MEMCACHE_SIZE_PASSWD
+              "' option from confdb.\n");
         return ret;
     }
 
@@ -266,7 +267,8 @@ static int setup_memcaches(struct nss_ctx *nctx)
                          &mc_size_group);
     if (ret != EOK) {
         DEBUG(SSSDBG_FATAL_FAILURE,
-              "Failed to get 'memcache_size_group' option from confdb.\n");
+              "Failed to get '"CONFDB_NSS_MEMCACHE_SIZE_GROUP
+              "' option from confdb.\n");
         return ret;
     }
 
@@ -277,7 +279,8 @@ static int setup_memcaches(struct nss_ctx *nctx)
                          &mc_size_initgroups);
     if (ret != EOK) {
         DEBUG(SSSDBG_FATAL_FAILURE,
-              "Failed to get 'memcache_size_nitgroups' option from confdb.\n");
+              "Failed to get '"CONFDB_NSS_MEMCACHE_SIZE_INITGROUPS
+              "' option from confdb.\n");
         return ret;
     }
 
@@ -291,8 +294,16 @@ static int setup_memcaches(struct nss_ctx *nctx)
                                   (time_t)memcache_timeout,
                                   &nctx->pwd_mc_ctx);
         if (ret) {
-            DEBUG(SSSDBG_CRIT_FAILURE, "passwd mmap cache is DISABLED\n");
+            DEBUG(SSSDBG_CRIT_FAILURE,
+                  "Failed to initialize passwd mmap cache: '%s'\n",
+                  sss_strerror(ret));
+        } else {
+            DEBUG(SSSDBG_CONF_SETTINGS, "Passwd mmap cache size is %d\n",
+                  mc_size_passwd);
         }
+    } else {
+        DEBUG(SSSDBG_IMPORTANT_INFO,
+              "Passwd mmap cache is explicitly DISABLED\n");
     }
 
     if (mc_size_group != 0) {
@@ -303,8 +314,16 @@ static int setup_memcaches(struct nss_ctx *nctx)
                                   (time_t)memcache_timeout,
                                   &nctx->grp_mc_ctx);
         if (ret) {
-            DEBUG(SSSDBG_CRIT_FAILURE, "group mmap cache is DISABLED\n");
+            DEBUG(SSSDBG_CRIT_FAILURE,
+                  "Failed to initialize group mmap cache: '%s'\n",
+                  sss_strerror(ret));
+        } else {
+            DEBUG(SSSDBG_CONF_SETTINGS, "Group mmap cache size is %d\n",
+                  mc_size_group);
         }
+    } else {
+        DEBUG(SSSDBG_IMPORTANT_INFO,
+              "Group mmap cache is explicitly DISABLED\n");
     }
 
     if (mc_size_initgroups != 0) {
@@ -315,8 +334,16 @@ static int setup_memcaches(struct nss_ctx *nctx)
                                   (time_t)memcache_timeout,
                                   &nctx->initgr_mc_ctx);
         if (ret) {
-            DEBUG(SSSDBG_CRIT_FAILURE, "initgroups mmap cache is DISABLED\n");
+            DEBUG(SSSDBG_CRIT_FAILURE,
+                  "Failed to initialize initgroups mmap cache: '%s'\n",
+                  sss_strerror(ret));
+        } else {
+            DEBUG(SSSDBG_CONF_SETTINGS, "Initgroups mmap cache size is %d\n",
+                  mc_size_initgroups);
         }
+    } else {
+        DEBUG(SSSDBG_IMPORTANT_INFO,
+              "Initgroups mmap cache is explicitly DISABLED\n");
     }
 
     return EOK;

From 8267db17e833d96b2a04dcb1e3e8b20b1ae1254c Mon Sep 17 00:00:00 2001
From: Alexey Tikhonov <atikh...@redhat.com>
Date: Wed, 4 Mar 2020 22:33:17 +0100
Subject: [PATCH 5/7] mem-cache: added log message in case cache is full

---
 src/responder/nss/nsssrv_mmap_cache.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/src/responder/nss/nsssrv_mmap_cache.c b/src/responder/nss/nsssrv_mmap_cache.c
index af7e865f32..18f0c6c5b5 100644
--- a/src/responder/nss/nsssrv_mmap_cache.c
+++ b/src/responder/nss/nsssrv_mmap_cache.c
@@ -371,6 +371,20 @@ static bool sss_mc_is_valid_rec(struct sss_mc_ctx *mcc, struct sss_mc_rec *rec)
     return true;
 }
 
+static const char *mc_type_to_str(enum sss_mc_type type)
+{
+    switch (type) {
+    case SSS_MC_PASSWD:
+        return "PASSWD";
+    case SSS_MC_GROUP:
+        return "GROUP";
+    case SSS_MC_INITGROUPS:
+        return "INITGROUPS";
+    default:
+        return "-UNKNOWN-";
+    }
+}
+
 /* FIXME: This is a very simplistic, inefficient, memory allocator,
  * it will just free the oldest entries regardless of expiration if it
  * cycled the whole free bits map and found no empty slot */
@@ -435,6 +449,12 @@ static errno_t sss_mc_find_free_slots(struct sss_mc_ctx *mcc,
     /* no free slots found, free occupied slots after next_slot */
     if ((mcc->next_slot + num_slots) > tot_slots) {
         cur = 0;
+        /* inform only once per full loop to avoid excessive spam */
+        DEBUG(SSSDBG_IMPORTANT_INFO, "mmap cache of type '%s' is full",
+              mc_type_to_str(mcc->type));
+        sss_log(SSS_LOG_NOTICE, "mmap cache of type '%s' is full, if you see "
+                "this message often then please consider increase of cache size",
+                mc_type_to_str(mcc->type));
     } else {
         cur = mcc->next_slot;
     }

From fe7043fd848fe3410bb4108b45990ef3316af35c Mon Sep 17 00:00:00 2001
From: Alexey Tikhonov <atikh...@redhat.com>
Date: Tue, 31 Mar 2020 16:27:25 +0200
Subject: [PATCH 6/7] mem-cache: always recycle the next set of slots

sss_mc_find_free_slots(): got rid of attempt to lookup free space;
always recycle the next set of slots.

For explanation look https://github.com/SSSD/sssd/pull/999#issuecomment-606657210

Relates: https://pagure.io/SSSD/sssd/issue/4160
---
 src/responder/nss/nsssrv_mmap_cache.c | 69 ++++++---------------------
 1 file changed, 15 insertions(+), 54 deletions(-)

diff --git a/src/responder/nss/nsssrv_mmap_cache.c b/src/responder/nss/nsssrv_mmap_cache.c
index 18f0c6c5b5..2f645e34d4 100644
--- a/src/responder/nss/nsssrv_mmap_cache.c
+++ b/src/responder/nss/nsssrv_mmap_cache.c
@@ -385,68 +385,29 @@ static const char *mc_type_to_str(enum sss_mc_type type)
     }
 }
 
-/* FIXME: This is a very simplistic, inefficient, memory allocator,
- * it will just free the oldest entries regardless of expiration if it
- * cycled the whole free bits map and found no empty slot */
+/* FIXME: This is a very simplistic, inefficient ring buffer,
+ * it will just rewrite the oldest entries regardless of expiration */
 static errno_t sss_mc_find_free_slots(struct sss_mc_ctx *mcc,
-                                      int num_slots, uint32_t *free_slot)
+                                      uint32_t num_slots, uint32_t *free_slot)
 {
+    const uint32_t tot_slots = mcc->ft_size * 8;
     struct sss_mc_rec *rec;
-    uint32_t tot_slots;
     uint32_t cur;
     uint32_t i;
-    uint32_t t;
     bool used;
 
-    tot_slots = mcc->ft_size * 8;
-
-    /* Try to find a free slot w/o removing anything first */
-    /* FIXME: Is it really worth it? Maybe it is easier to
-     * just recycle the next set of slots? */
-    if ((mcc->next_slot + num_slots) > tot_slots) {
-        cur = 0;
-    } else {
-        cur = mcc->next_slot;
-    }
-
-    /* search for enough (num_slots) consecutive zero bits, indicating
-     * consecutive empty slots */
-    for (i = 0; i < mcc->ft_size; i++) {
-        t = cur / 8;
-        /* if all full in this byte skip directly to the next */
-        if (mcc->free_table[t] == 0xff) {
-            cur = ((cur + 8) & ~7);
-            if (cur >= tot_slots) {
-                cur = 0;
-            }
-            continue;
-        }
-
-        /* at least one bit in this byte is marked as empty */
-        for (t = ((cur + 8) & ~7) ; cur < t; cur++) {
-            MC_PROBE_BIT(mcc->free_table, cur, used);
-            if (!used) break;
-        }
-        /* check if we have enough slots before hitting the table end */
-        if ((cur + num_slots) > tot_slots) {
-            cur = 0;
-            continue;
-        }
-
-        /* check if we have at least num_slots empty starting from the first
-         * we found in the previous steps */
-        for (t = cur + num_slots; cur < t; cur++) {
-            MC_PROBE_BIT(mcc->free_table, cur, used);
-            if (used) break;
-        }
-        if (cur == t) {
-            /* ok found num_slots consecutive free bits */
-            *free_slot = cur - num_slots;
-            return EOK;
-        }
+    if (num_slots > tot_slots) {
+        DEBUG(SSSDBG_CRIT_FAILURE,
+              "mmap cache of type '%s': %u slots of %u total were requested",
+              mc_type_to_str(mcc->type), num_slots, tot_slots);
+        sss_log(SSS_LOG_NOTICE,
+                "mmap cache of type '%s': %u slots of %u total were requested,"
+                " consider increase of cache size",
+                mc_type_to_str(mcc->type), num_slots, tot_slots);
+        return EFAULT;
     }
 
-    /* no free slots found, free occupied slots after next_slot */
+    /* always recycle the next set of slots */
     if ((mcc->next_slot + num_slots) > tot_slots) {
         cur = 0;
         /* inform only once per full loop to avoid excessive spam */
@@ -613,7 +574,7 @@ static errno_t sss_mc_get_record(struct sss_mc_ctx **_mcc,
     struct sss_mc_rec *old_rec = NULL;
     struct sss_mc_rec *rec;
     int old_slots;
-    int num_slots;
+    uint32_t num_slots;
     uint32_t base_slot;
     errno_t ret;
     int i;

From 0f0f21f6d3e14b34e6457c391178c323c2b902c9 Mon Sep 17 00:00:00 2001
From: Alexey Tikhonov <atikh...@redhat.com>
Date: Tue, 31 Mar 2020 22:57:25 +0200
Subject: [PATCH 7/7] NSS: make memcache size configurable in megabytes

Memcache size was made configurable in megabytes and not in slots
to hide internal implementation from users.

Relates: https://pagure.io/SSSD/sssd/issue/4160
---
 src/man/sssd.conf.5.xml    | 33 +++++++++++++++------------------
 src/responder/nss/nsssrv.c | 20 +++++++++++---------
 2 files changed, 26 insertions(+), 27 deletions(-)

diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml
index e41d061dc6..3fe81564ad 100644
--- a/src/man/sssd.conf.5.xml
+++ b/src/man/sssd.conf.5.xml
@@ -1076,7 +1076,7 @@ fallback_homedir = /home/%u
                     </listitem>
                 </varlistentry>
                 <varlistentry>
-                    <term>memcache_timeout (int)</term>
+                    <term>memcache_timeout (integer)</term>
                     <listitem>
                         <para>
                             Specifies time in seconds for which records
@@ -1104,14 +1104,13 @@ fallback_homedir = /home/%u
                     <term>memcache_size_passwd (integer)</term>
                     <listitem>
                         <para>
-                            Number of slots allocated inside fast in-memory
-                            cache for passwd requests. Note that one entry
-                            in fast in-memory cache can occupy more than one slot.
-                            Setting the size to 0 will disable the passwd in-memory
-                            cache.
+                            Size (in megabytes) of the data table allocated inside
+                            fast in-memory cache for passwd requests.
+                            Setting the size to 0 will disable the passwd
+                            in-memory cache.
                         </para>
                         <para>
-                            Default: 200000
+                            Default: 8
                         </para>
                         <para>
                             WARNING: Disabled or too small in-memory cache can
@@ -1130,14 +1129,13 @@ fallback_homedir = /home/%u
                     <term>memcache_size_group (integer)</term>
                     <listitem>
                         <para>
-                            Number of slots allocated inside fast in-memory
-                            cache for group requests. Note that one entry
-                            in fast in-memory cache can occupy more than one
-                            slot. Setting the size to 0 will disable the group
+                            Size (in megabytes) of the data table allocated inside
+                            fast in-memory cache for group requests.
+                            Setting the size to 0 will disable the group
                             in-memory cache.
                         </para>
                         <para>
-                            Default: 150000
+                            Default: 6
                         </para>
                         <para>
                             WARNING: Disabled or too small in-memory cache can
@@ -1156,14 +1154,13 @@ fallback_homedir = /home/%u
                     <term>memcache_size_initgroups (integer)</term>
                     <listitem>
                         <para>
-                            Number of slots allocated inside fast in-memory
-                            cache for initgroups requests. Note that one entry
-                            in fast in-memory cache can occupy more than one
-                            slot. Setting the size to 0 will disable the
-                            initgroups in-memory cache.
+                            Size (in megabytes) of the data table allocated inside
+                            fast in-memory cache for initgroups requests.
+                            Setting the size to 0 will disable the initgroups
+                            in-memory cache.
                         </para>
                         <para>
-                            Default: 250000
+                            Default: 10
                         </para>
                         <para>
                             WARNING: Disabled or too small in-memory cache can
diff --git a/src/responder/nss/nsssrv.c b/src/responder/nss/nsssrv.c
index 5f8d9e3478..18a8817481 100644
--- a/src/responder/nss/nsssrv.c
+++ b/src/responder/nss/nsssrv.c
@@ -34,6 +34,7 @@
 
 #include "util/util.h"
 #include "util/sss_ptr_hash.h"
+#include "util/mmap_cache.h"
 #include "responder/nss/nss_private.h"
 #include "responder/nss/nss_iface.h"
 #include "responder/nss/nsssrv_mmap_cache.h"
@@ -210,9 +211,10 @@ static int nss_get_config(struct nss_ctx *nctx,
 static int setup_memcaches(struct nss_ctx *nctx)
 {
     /* Default memcache sizes */
-    static const size_t SSS_MC_CACHE_PASSWD_SLOTS    = 200000;  /*  8mb */
-    static const size_t SSS_MC_CACHE_GROUP_SLOTS     = 150000;  /*  6mb */
-    static const size_t SSS_MC_CACHE_INITGROUP_SLOTS = 250000;  /* 10mb */
+    static const size_t SSS_MC_CACHE_SLOTS_PER_MB   = 1024*1024/MC_SLOT_SIZE;
+    static const size_t SSS_MC_CACHE_PASSWD_SIZE    =  8;
+    static const size_t SSS_MC_CACHE_GROUP_SIZE     =  6;
+    static const size_t SSS_MC_CACHE_INITGROUP_SIZE = 10;
 
     int ret;
     int memcache_timeout;
@@ -251,7 +253,7 @@ static int setup_memcaches(struct nss_ctx *nctx)
     ret = confdb_get_int(nctx->rctx->cdb,
                          CONFDB_NSS_CONF_ENTRY,
                          CONFDB_NSS_MEMCACHE_SIZE_PASSWD,
-                         SSS_MC_CACHE_PASSWD_SLOTS,
+                         SSS_MC_CACHE_PASSWD_SIZE,
                          &mc_size_passwd);
     if (ret != EOK) {
         DEBUG(SSSDBG_FATAL_FAILURE,
@@ -263,7 +265,7 @@ static int setup_memcaches(struct nss_ctx *nctx)
     ret = confdb_get_int(nctx->rctx->cdb,
                          CONFDB_NSS_CONF_ENTRY,
                          CONFDB_NSS_MEMCACHE_SIZE_GROUP,
-                         SSS_MC_CACHE_GROUP_SLOTS,
+                         SSS_MC_CACHE_GROUP_SIZE,
                          &mc_size_group);
     if (ret != EOK) {
         DEBUG(SSSDBG_FATAL_FAILURE,
@@ -275,7 +277,7 @@ static int setup_memcaches(struct nss_ctx *nctx)
     ret = confdb_get_int(nctx->rctx->cdb,
                          CONFDB_NSS_CONF_ENTRY,
                          CONFDB_NSS_MEMCACHE_SIZE_INITGROUPS,
-                         SSS_MC_CACHE_INITGROUP_SLOTS,
+                         SSS_MC_CACHE_INITGROUP_SIZE,
                          &mc_size_initgroups);
     if (ret != EOK) {
         DEBUG(SSSDBG_FATAL_FAILURE,
@@ -290,7 +292,7 @@ static int setup_memcaches(struct nss_ctx *nctx)
         ret = sss_mmap_cache_init(nctx, "passwd",
                                   nctx->mc_uid, nctx->mc_gid,
                                   SSS_MC_PASSWD,
-                                  mc_size_passwd,
+                                  mc_size_passwd * SSS_MC_CACHE_SLOTS_PER_MB,
                                   (time_t)memcache_timeout,
                                   &nctx->pwd_mc_ctx);
         if (ret) {
@@ -310,7 +312,7 @@ static int setup_memcaches(struct nss_ctx *nctx)
         ret = sss_mmap_cache_init(nctx, "group",
                                   nctx->mc_uid, nctx->mc_gid,
                                   SSS_MC_GROUP,
-                                  mc_size_group,
+                                  mc_size_group * SSS_MC_CACHE_SLOTS_PER_MB,
                                   (time_t)memcache_timeout,
                                   &nctx->grp_mc_ctx);
         if (ret) {
@@ -330,7 +332,7 @@ static int setup_memcaches(struct nss_ctx *nctx)
         ret = sss_mmap_cache_init(nctx, "initgroups",
                                   nctx->mc_uid, nctx->mc_gid,
                                   SSS_MC_INITGROUPS,
-                                  mc_size_initgroups,
+                                  mc_size_initgroups * SSS_MC_CACHE_SLOTS_PER_MB,
                                   (time_t)memcache_timeout,
                                   &nctx->initgr_mc_ctx);
         if (ret) {
_______________________________________________
sssd-devel mailing list -- sssd-devel@lists.fedorahosted.org
To unsubscribe send an email to sssd-devel-le...@lists.fedorahosted.org
Fedora Code of Conduct: 
https://docs.fedoraproject.org/en-US/project/code-of-conduct/
List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines
List Archives: 
https://lists.fedorahosted.org/archives/list/sssd-devel@lists.fedorahosted.org

Reply via email to