Blame SOURCES/0029-Ticket-49204-Fix-lower-bounds-on-import-autosize-On-.patch

61f723
From 9be74e83539e204e9a56721da5c22bd9abf38195 Mon Sep 17 00:00:00 2001
61f723
From: Mark Reynolds <mreynolds@redhat.com>
61f723
Date: Wed, 19 Apr 2017 13:41:22 -0400
61f723
Subject: [PATCH] Ticket 49204 - Fix lower bounds on import autosize + On small
61f723
 VM, autotune breaks the access of the suffixes
61f723
61f723
    Bug Description:
61f723
        ldif2db in some cases may set a cache of 0, which may y break imports.
61f723
61f723
        Under memory pressure, the amount of available memory at startup
61f723
        can be so low that the configured cachememsize will be rejected
61f723
        (unwilling to perform).
61f723
        This should leave the cachememsize being "0" (default)
61f723
        This conduct to be unable to access the suffix pages.
61f723
61f723
    Fix Description:
61f723
61f723
     * autosize set an incorrect percentage which was too high.
61f723
     * we did not check the lower bound of the allocation
61f723
       so we now set that we must have a minimum allocation.
61f723
     * Set entrycache to a minimal value, even if it looks insane
61f723
     * add a cap on reduction of caches, so we always allocate a few pages
61f723
       at least, and prevent returning 0 to the caller.
61f723
61f723
    https://pagure.io/389-ds-base/issue/49204
61f723
61f723
    Author: wibrown, tbordaz
61f723
61f723
    Review by: tbordaz (Thanks mate, great work with this :) )
61f723
---
61f723
 ldap/servers/slapd/back-ldbm/cache.c               |  4 +--
61f723
 ldap/servers/slapd/back-ldbm/dblayer.c             | 33 +++++++++++++---------
61f723
 ldap/servers/slapd/back-ldbm/dblayer.h             | 12 ++++----
61f723
 ldap/servers/slapd/back-ldbm/ldbm_config.c         |  4 +--
61f723
 .../servers/slapd/back-ldbm/ldbm_instance_config.c | 23 +++++++++++++--
61f723
 ldap/servers/slapd/slapi-private.h                 |  2 +-
61f723
 ldap/servers/slapd/util.c                          | 20 +++++++++----
61f723
 7 files changed, 65 insertions(+), 33 deletions(-)
61f723
61f723
diff --git a/ldap/servers/slapd/back-ldbm/cache.c b/ldap/servers/slapd/back-ldbm/cache.c
61f723
index 0f0cf3b..c6638a2 100644
61f723
--- a/ldap/servers/slapd/back-ldbm/cache.c
61f723
+++ b/ldap/servers/slapd/back-ldbm/cache.c
61f723
@@ -65,7 +65,7 @@
61f723
 
61f723
 /* static functions */
61f723
 static void entrycache_clear_int(struct cache *cache);
61f723
-static void entrycache_set_max_size(struct cache *cache, size_t bytes);
61f723
+static void entrycache_set_max_size(struct cache *cache, uint64_t bytes);
61f723
 static int entrycache_remove_int(struct cache *cache, struct backentry *e);
61f723
 static void entrycache_return(struct cache *cache, struct backentry **bep);
61f723
 static int entrycache_replace(struct cache *cache, struct backentry *olde, struct backentry *newe);
61f723
@@ -77,7 +77,7 @@ static void entry_lru_verify(struct cache *cache, struct backentry *e, int in);
61f723
 
61f723
 static int dn_same_id(const void *bdn, const void *k);
61f723
 static void dncache_clear_int(struct cache *cache);
61f723
-static void dncache_set_max_size(struct cache *cache, size_t bytes);
61f723
+static void dncache_set_max_size(struct cache *cache, uint64_t bytes);
61f723
 static int dncache_remove_int(struct cache *cache, struct backdn *dn);
61f723
 static void dncache_return(struct cache *cache, struct backdn **bdn);
61f723
 static int dncache_replace(struct cache *cache, struct backdn *olddn, struct backdn *newdn);
61f723
diff --git a/ldap/servers/slapd/back-ldbm/dblayer.c b/ldap/servers/slapd/back-ldbm/dblayer.c
61f723
index 3c1fbb0..f834322 100644
61f723
--- a/ldap/servers/slapd/back-ldbm/dblayer.c
61f723
+++ b/ldap/servers/slapd/back-ldbm/dblayer.c
61f723
@@ -1237,8 +1237,8 @@ no_diskspace(struct ldbminfo *li, int dbenv_flags)
61f723
     struct statvfs db_buf;
61f723
     int using_region_files = !(dbenv_flags & ( DB_PRIVATE | DB_SYSTEM_MEM));
61f723
     /* value of 10 == 10% == little more than the average overhead calculated for very large files on 64-bit system for bdb 4.7 */
61f723
-    PRUint64 expected_siz = li->li_dbcachesize + li->li_dbcachesize/10; /* dbcache + region files */
61f723
-    PRUint64 fsiz;
61f723
+    uint64_t expected_siz = li->li_dbcachesize + li->li_dbcachesize/10; /* dbcache + region files */
61f723
+    uint64_t fsiz;
61f723
     char *region_dir;
61f723
 
61f723
     if (statvfs(li->li_directory, &db_buf) < 0){
61f723
@@ -1263,7 +1263,7 @@ no_diskspace(struct ldbminfo *li, int dbenv_flags)
61f723
                         li->li_dblayer_private->dblayer_dbhome_directory);
61f723
                     return 1;
61f723
                 }
61f723
-                fsiz = ((PRUint64)dbhome_buf.f_bavail) * ((PRUint64)dbhome_buf.f_bsize);
61f723
+                fsiz = ((uint64_t)dbhome_buf.f_bavail) * ((uint64_t)dbhome_buf.f_bsize);
61f723
                 region_dir = li->li_dblayer_private->dblayer_dbhome_directory;
61f723
             } else {
61f723
                 /* Shared/private memory.  No need to check disk space, return success */
61f723
@@ -1387,12 +1387,17 @@ dblayer_start(struct ldbminfo *li, int dbmode)
61f723
     /* Sanity check on cache size on platforms which allow us to figure out
61f723
      * the available phys mem */
61f723
     slapi_pal_meminfo *mi = spal_meminfo_get();
61f723
-    if (!util_is_cachesize_sane(mi, &(priv->dblayer_cachesize))) {
61f723
+    util_cachesize_result result = util_is_cachesize_sane(mi, &(priv->dblayer_cachesize));
61f723
+    if (result == UTIL_CACHESIZE_ERROR) {
61f723
+        slapi_log_err(SLAPI_LOG_CRIT, "dblayer_start", "Unable to determine if cachesize was valid!!!");
61f723
+    } else if (result == UTIL_CACHESIZE_REDUCED) {
61f723
+        /* In some cases we saw this go to 0, prevent this. */
61f723
+        if (priv->dblayer_cachesize < MINCACHESIZE) {
61f723
+            priv->dblayer_cachesize = MINCACHESIZE;
61f723
+        }
61f723
         /* Oops---looks like the admin misconfigured, let's warn them */
61f723
-        slapi_log_err(SLAPI_LOG_WARNING,"dblayer_start", "Likely CONFIGURATION ERROR -"
61f723
-                  "dbcachesize is configured to use more than the available "
61f723
-                  "physical memory, decreased to the largest available size (%"PRIu64" bytes).\n",
61f723
-                  priv->dblayer_cachesize);
61f723
+        slapi_log_err(SLAPI_LOG_WARNING, "dblayer_start", "Likely CONFIGURATION ERROR - dbcachesize is configured to use more than the available "
61f723
+                  "memory, decreased to (%"PRIu64" bytes).\n", priv->dblayer_cachesize);
61f723
         li->li_dbcachesize = priv->dblayer_cachesize;
61f723
     }
61f723
     spal_meminfo_destroy(mi);
61f723
@@ -3816,7 +3821,7 @@ static const u_int32_t default_flags = DB_NEXT;
61f723
 typedef struct txn_test_iter {
61f723
     DB *db;
61f723
     DBC *cur;
61f723
-    size_t cnt;
61f723
+    uint64_t cnt;
61f723
     const char *attr;
61f723
     u_int32_t flags;
61f723
     backend *be;
61f723
@@ -3938,10 +3943,10 @@ static int txn_test_threadmain(void *param)
61f723
     Object *inst_obj;
61f723
     int rc = 0;
61f723
     txn_test_iter **ttilist = NULL;
61f723
-    size_t tticnt = 0;
61f723
+    uint64_t tticnt = 0;
61f723
     DB_TXN *txn = NULL;
61f723
     txn_test_cfg cfg = {0};
61f723
-    size_t counter = 0;
61f723
+    uint64_t counter = 0;
61f723
     char keybuf[8192];
61f723
     char databuf[8192];
61f723
     int dbattempts = 0;
61f723
@@ -4062,9 +4067,9 @@ retry_txn:
61f723
         if (!rc) {
61f723
             DBT key;
61f723
             DBT data;
61f723
-            size_t ii;
61f723
-            size_t donecnt = 0;
61f723
-            size_t cnt = 0;
61f723
+            uint64_t ii;
61f723
+            uint64_t donecnt = 0;
61f723
+            uint64_t cnt = 0;
61f723
 
61f723
             /* phase 1 - open a cursor to each db */
61f723
             if (cfg.verbose) {
61f723
diff --git a/ldap/servers/slapd/back-ldbm/dblayer.h b/ldap/servers/slapd/back-ldbm/dblayer.h
61f723
index 816c943..77b04fa 100644
61f723
--- a/ldap/servers/slapd/back-ldbm/dblayer.h
61f723
+++ b/ldap/servers/slapd/back-ldbm/dblayer.h
61f723
@@ -90,8 +90,8 @@ struct dblayer_private
61f723
     int dblayer_ncache;
61f723
     int dblayer_previous_ncache;
61f723
     int dblayer_tx_max;
61f723
-    size_t dblayer_cachesize;
61f723
-    size_t dblayer_previous_cachesize; /* Cache size when we last shut down--
61f723
+    uint64_t dblayer_cachesize;
61f723
+    uint64_t dblayer_previous_cachesize; /* Cache size when we last shut down--
61f723
                                         * used to determine if we delete 
61f723
                                         * the mpool */
61f723
     int dblayer_recovery_required;
61f723
@@ -102,15 +102,15 @@ struct dblayer_private
61f723
     int dblayer_durable_transactions;
61f723
     int dblayer_checkpoint_interval;
61f723
     int dblayer_circular_logging;
61f723
-    size_t dblayer_page_size;       /* db page size if configured,
61f723
+    uint64_t dblayer_page_size;       /* db page size if configured,
61f723
                                      * otherwise default to DBLAYER_PAGESIZE */
61f723
-    size_t dblayer_index_page_size; /* db index page size if configured,
61f723
+    uint64_t dblayer_index_page_size; /* db index page size if configured,
61f723
                                      * otherwise default to 
61f723
                                      * DBLAYER_INDEX_PAGESIZE */
61f723
     int dblayer_idl_divisor;        /* divide page size by this to get IDL 
61f723
                                      * size */
61f723
-    size_t dblayer_logfile_size;    /* How large can one logfile be ? */
61f723
-    size_t dblayer_logbuf_size;     /* how large log buffer can be */
61f723
+    uint64_t dblayer_logfile_size;    /* How large can one logfile be ? */
61f723
+    uint64_t dblayer_logbuf_size;     /* how large log buffer can be */
61f723
     int dblayer_file_mode;          /* pmode for files we create */
61f723
     int dblayer_verbose;            /* Get libdb to exhale debugging info */
61f723
     int dblayer_debug;              /* Will libdb emit debugging info into 
61f723
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_config.c b/ldap/servers/slapd/back-ldbm/ldbm_config.c
61f723
index d5120d3..401cd60 100644
61f723
--- a/ldap/servers/slapd/back-ldbm/ldbm_config.c
61f723
+++ b/ldap/servers/slapd/back-ldbm/ldbm_config.c
61f723
@@ -1582,9 +1582,9 @@ static config_info ldbm_config[] = {
61f723
     {CONFIG_DB_DEBUG_CHECKPOINTING, CONFIG_TYPE_ONOFF, "off", &ldbm_config_db_debug_checkpointing_get, &ldbm_config_db_debug_checkpointing_set, 0},
61f723
     {CONFIG_DB_HOME_DIRECTORY, CONFIG_TYPE_STRING, "", &ldbm_config_db_home_directory_get, &ldbm_config_db_home_directory_set, 0},
61f723
     {CONFIG_IMPORT_CACHE_AUTOSIZE, CONFIG_TYPE_INT, "-1", &ldbm_config_import_cache_autosize_get, &ldbm_config_import_cache_autosize_set, CONFIG_FLAG_ALWAYS_SHOW|CONFIG_FLAG_ALLOW_RUNNING_CHANGE},
61f723
-    {CONFIG_CACHE_AUTOSIZE, CONFIG_TYPE_INT, "0", &ldbm_config_cache_autosize_get, &ldbm_config_cache_autosize_set, 0},
61f723
+    {CONFIG_CACHE_AUTOSIZE, CONFIG_TYPE_INT, "10", &ldbm_config_cache_autosize_get, &ldbm_config_cache_autosize_set, 0},
61f723
     {CONFIG_CACHE_AUTOSIZE_SPLIT, CONFIG_TYPE_INT, "40", &ldbm_config_cache_autosize_split_get, &ldbm_config_cache_autosize_split_set, 0},
61f723
-    {CONFIG_IMPORT_CACHESIZE, CONFIG_TYPE_SIZE_T, "20000000", &ldbm_config_import_cachesize_get, &ldbm_config_import_cachesize_set, CONFIG_FLAG_ALWAYS_SHOW|CONFIG_FLAG_ALLOW_RUNNING_CHANGE},
61f723
+    {CONFIG_IMPORT_CACHESIZE, CONFIG_TYPE_SIZE_T, "16777216", &ldbm_config_import_cachesize_get, &ldbm_config_import_cachesize_set, CONFIG_FLAG_ALWAYS_SHOW|CONFIG_FLAG_ALLOW_RUNNING_CHANGE},
61f723
     {CONFIG_IDL_SWITCH, CONFIG_TYPE_STRING, "new", &ldbm_config_idl_get_idl_new, &ldbm_config_idl_set_tune, CONFIG_FLAG_ALWAYS_SHOW},
61f723
     {CONFIG_IDL_UPDATE, CONFIG_TYPE_ONOFF, "on", &ldbm_config_idl_get_update, &ldbm_config_idl_set_update, 0},
61f723
     {CONFIG_BYPASS_FILTER_TEST, CONFIG_TYPE_STRING, "on", &ldbm_config_get_bypass_filter_test, &ldbm_config_set_bypass_filter_test, CONFIG_FLAG_ALWAYS_SHOW|CONFIG_FLAG_ALLOW_RUNNING_CHANGE},
61f723
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c b/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c
61f723
index 62cdbc3..36d830d 100644
61f723
--- a/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c
61f723
+++ b/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c
61f723
@@ -93,6 +93,7 @@ ldbm_instance_config_cachememsize_set(void *arg, void *value, char *errorbuf, in
61f723
     int retval = LDAP_SUCCESS;
61f723
     size_t val = (size_t) value;
61f723
     uint64_t delta = 0;
61f723
+    uint64_t delta_original = 0;
61f723
 
61f723
     /* Do whatever we can to make sure the data is ok. */
61f723
     /* There is an error here. We check the new val against our current mem-alloc 
61f723
@@ -108,18 +109,34 @@ ldbm_instance_config_cachememsize_set(void *arg, void *value, char *errorbuf, in
61f723
     if (apply) {
61f723
         if (val > inst->inst_cache.c_maxsize) {
61f723
             delta = val - inst->inst_cache.c_maxsize;
61f723
+            delta_original = delta;
61f723
 
61f723
             util_cachesize_result sane;
61f723
             slapi_pal_meminfo *mi = spal_meminfo_get();
61f723
             sane = util_is_cachesize_sane(mi, &delta);
61f723
             spal_meminfo_destroy(mi);
61f723
 
61f723
-            if (sane != UTIL_CACHESIZE_VALID){
61f723
-                slapi_create_errormsg(errorbuf, SLAPI_DSE_RETURNTEXT_SIZE, "Error: cachememsize value is too large.");
61f723
-                slapi_log_err(SLAPI_LOG_ERR, "ldbm_instance_config_cachememsize_set", "cachememsize value is too large.\n");
61f723
+            if (sane == UTIL_CACHESIZE_ERROR){
61f723
+                slapi_create_errormsg(errorbuf, SLAPI_DSE_RETURNTEXT_SIZE, "Error: unable to determine system memory limits.");
61f723
+                slapi_log_err(SLAPI_LOG_ERR, "ldbm_instance_config_cachememsize_set", "Enable to determine system memory limits.\n");
61f723
                 return LDAP_UNWILLING_TO_PERFORM;
61f723
+            } else if (sane == UTIL_CACHESIZE_REDUCED) {
61f723
+                slapi_log_err(SLAPI_LOG_WARNING, "ldbm_instance_config_cachememsize_set", "delta +%"PRIu64" of request %"PRIu64" reduced to %"PRIu64"\n", delta_original, val, delta);
61f723
+                /*
61f723
+                 * This works as: value = 100
61f723
+                 * delta_original to inst, 20;
61f723
+                 * delta reduced to 5:
61f723
+                 * 100 - (20 - 5) == 85;
61f723
+                 * so if you recalculated delta now (val - inst), it would be 5.
61f723
+                 */
61f723
+                val = val - (delta_original - delta);
61f723
             }
61f723
         }
61f723
+        if (inst->inst_cache.c_maxsize < MINCACHESIZE || val < MINCACHESIZE) {
61f723
+            slapi_log_err(SLAPI_LOG_ERR, "ldbm_instance_config_cachememsize_set", "force a minimal value %"PRIu64"\n", MINCACHESIZE);
61f723
+            /* This value will trigger an autotune next start up, but it should increase only */
61f723
+            val = MINCACHESIZE;
61f723
+        }
61f723
         cache_set_max_size(&(inst->inst_cache), val, CACHE_TYPE_ENTRY);
61f723
     }
61f723
 
61f723
diff --git a/ldap/servers/slapd/slapi-private.h b/ldap/servers/slapd/slapi-private.h
61f723
index 0c76580..d9547d8 100644
61f723
--- a/ldap/servers/slapd/slapi-private.h
61f723
+++ b/ldap/servers/slapd/slapi-private.h
61f723
@@ -1392,7 +1392,7 @@ typedef enum _util_cachesize_result {
61f723
  * \return util_cachesize_result.
61f723
  * \sa util_cachesize_result, spal_meminfo_get
61f723
  */
61f723
-util_cachesize_result util_is_cachesize_sane(slapi_pal_meminfo *mi, size_t *cachesize);
61f723
+util_cachesize_result util_is_cachesize_sane(slapi_pal_meminfo *mi, uint64_t *cachesize);
61f723
 
61f723
 /**
61f723
  * Retrieve the number of threads the server should run with based on this hardware.
61f723
diff --git a/ldap/servers/slapd/util.c b/ldap/servers/slapd/util.c
61f723
index 012e83d..4ff6d41 100644
61f723
--- a/ldap/servers/slapd/util.c
61f723
+++ b/ldap/servers/slapd/util.c
61f723
@@ -1468,16 +1468,26 @@ util_is_cachesize_sane(slapi_pal_meminfo *mi, uint64_t *cachesize)
61f723
         return UTIL_CACHESIZE_ERROR;
61f723
     }
61f723
 
61f723
+    util_cachesize_result result = UTIL_CACHESIZE_VALID;
61f723
     slapi_log_err(SLAPI_LOG_TRACE, "util_is_cachesize_sane", "Available bytes %"PRIu64", requested bytes %"PRIu64"\n", mi->system_available_bytes, *cachesize);
61f723
     if (*cachesize > mi->system_available_bytes) {
61f723
-        /* Since we are ask for more than what's available, we give 3/4 of the remaining.
61f723
+        /* Since we are ask for more than what's available, we give 1/2 of the remaining.
61f723
          * the remaining system mem to the cachesize instead, and log a warning
61f723
          */
61f723
-        *cachesize = (mi->system_available_bytes * 0.75);
61f723
-        slapi_log_err(SLAPI_LOG_TRACE, "util_is_cachesize_sane", "Adjusted cachesize to %"PRIu64"\n", *cachesize);
61f723
-        return UTIL_CACHESIZE_REDUCED;
61f723
+        uint64_t adjust_cachesize = (mi->system_available_bytes * 0.5);
61f723
+        if (adjust_cachesize > *cachesize) {
61f723
+            slapi_log_err(SLAPI_LOG_CRIT, "util_is_cachesize_sane", "Invalid adjusted cachesize is greater than request %"PRIu64, adjust_cachesize);
61f723
+            return UTIL_CACHESIZE_ERROR;
61f723
+        }
61f723
+        if (adjust_cachesize < (16 * mi->pagesize_bytes)) {
61f723
+            /* At minimum respond with 16 pages - that's 64k on x86_64 */
61f723
+            adjust_cachesize = 16 * mi->pagesize_bytes;
61f723
+        }
61f723
+        *cachesize = adjust_cachesize;
61f723
+        slapi_log_err(SLAPI_LOG_TRACE, "util_is_cachesize_sane", "Adjusted cachesize down to %"PRIu64"\n", *cachesize);
61f723
+        result = UTIL_CACHESIZE_REDUCED;
61f723
     }
61f723
-    return UTIL_CACHESIZE_VALID;
61f723
+    return result;
61f723
 }
61f723
 
61f723
 long
61f723
-- 
61f723
2.9.3
61f723