From e2fdc9a02ad824ba9f977ca8b8586b0dc22b4aee Mon Sep 17 00:00:00 2001 From: Quanah Gibson-Mount Date: Mon, 27 Jul 2009 19:38:40 +0000 Subject: [PATCH] ITS#6222 --- CHANGES | 1 + doc/man/man5/slapd-bdb.5 | 7 ++++--- servers/slapd/back-bdb/back-bdb.h | 16 +++++++------- servers/slapd/back-bdb/cache.c | 35 ++++++++++++++++--------------- servers/slapd/back-bdb/config.c | 8 +++---- servers/slapd/back-bdb/idl.c | 3 ++- servers/slapd/back-bdb/init.c | 11 ++++------ servers/slapd/back-bdb/monitor.c | 6 +++--- servers/slapd/config.c | 15 +++++++++++++ servers/slapd/config.h | 3 +++ 10 files changed, 62 insertions(+), 43 deletions(-) diff --git a/CHANGES b/CHANGES index 2aac951be9..bc32a3f92e 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,7 @@ OpenLDAP 2.4 Change Log OpenLDAP 2.4.18 Engineering + Fixed slapd dncachesize behavior to unlimited by default (ITS#6222) Fixed slapd incorrectly applying writetimeout when not set (ITS#6220) Fixed slapd subordinate needs a suffix (ITS#6216) Fixed slapd tools to properly close database (ITS#6214) diff --git a/doc/man/man5/slapd-bdb.5 b/doc/man/man5/slapd-bdb.5 index f0a6d4cf92..d18638173a 100644 --- a/doc/man/man5/slapd-bdb.5 +++ b/doc/man/man5/slapd-bdb.5 @@ -145,11 +145,12 @@ In this case, the modified data is discarded and a subsequent search will return a different result. .TP .BI dncachesize \ -Specify the maximum number of DNs in the in-memory DN cache. The -default is twice the \fBcachesize\fP. Ideally this cache should be +Specify the maximum number of DNs in the in-memory DN cache. +Ideally this cache should be large enough to contain the DNs of every entry in the database. If set to a smaller value than the \fBcachesize\fP it will be silently -increased to equal the \fBcachesize\fP. +increased to equal the \fBcachesize\fP. The default value is 0 which +means unlimited, i.e. the DN cache will grow without bound. It should be noted that the \fBDN cache\fP is allowed to temporarily grow beyond the configured size. It does this if many entries are diff --git a/servers/slapd/back-bdb/back-bdb.h b/servers/slapd/back-bdb/back-bdb.h index 0219e3ff14..1ea9f84f16 100644 --- a/servers/slapd/back-bdb/back-bdb.h +++ b/servers/slapd/back-bdb/back-bdb.h @@ -125,12 +125,12 @@ typedef struct bdb_cache { EntryInfo *c_lruhead; /* lru - add accessed entries here */ EntryInfo *c_lrutail; /* lru - rem lru entries from here */ EntryInfo c_dntree; - unsigned c_maxsize; - int c_cursize; - unsigned c_minfree; - unsigned c_eimax; - int c_eiused; /* EntryInfo's in use */ - int c_leaves; /* EntryInfo leaf nodes */ + ID c_maxsize; + ID c_cursize; + ID c_minfree; + ID c_eimax; + ID c_eiused; /* EntryInfo's in use */ + ID c_leaves; /* EntryInfo leaf nodes */ int c_purging; DB_TXN *c_txn; /* used by lru cleaner */ ldap_pvt_thread_rdwr_t c_rwlock; @@ -204,8 +204,8 @@ struct bdb_info { ID bi_lastid; ldap_pvt_thread_mutex_t bi_lastid_mutex; - unsigned bi_idl_cache_max_size; - int bi_idl_cache_size; + ID bi_idl_cache_max_size; + ID bi_idl_cache_size; Avlnode *bi_idl_tree; bdb_idl_cache_entry_t *bi_idl_lru_head; bdb_idl_cache_entry_t *bi_idl_lru_tail; diff --git a/servers/slapd/back-bdb/cache.c b/servers/slapd/back-bdb/cache.c index 5d36a2db29..a6ba2b9b36 100644 --- a/servers/slapd/back-bdb/cache.c +++ b/servers/slapd/back-bdb/cache.c @@ -689,8 +689,9 @@ bdb_cache_lru_purge( struct bdb_info *bdb ) { DB_LOCK lock, *lockp; EntryInfo *elru, *elnext = NULL; - int count, islocked, eimax; - int efree = 0, eifree = 0, eicount, ecount; + int islocked; + ID eicount, ecount; + ID count, efree, eifree = 0; #ifdef LDAP_DEBUG int iter; #endif @@ -698,24 +699,24 @@ bdb_cache_lru_purge( struct bdb_info *bdb ) /* Wait for the mutex; we're the only one trying to purge. */ ldap_pvt_thread_mutex_lock( &bdb->bi_cache.c_lru_mutex ); + if ( bdb->bi_cache.c_cursize > bdb->bi_cache.c_maxsize ) { + efree = bdb->bi_cache.c_cursize - bdb->bi_cache.c_maxsize; + efree += bdb->bi_cache.c_minfree; + } else { + efree = 0; + } + /* maximum number of EntryInfo leaves to cache. In slapcat * we always free all leaf nodes. */ - if ( slapMode & SLAP_TOOL_READONLY ) - eimax = 0; - else - eimax = bdb->bi_cache.c_eimax; - - efree = bdb->bi_cache.c_cursize - bdb->bi_cache.c_maxsize; - if ( efree < 1 ) - efree = 0; - else - efree += bdb->bi_cache.c_minfree; - if ( bdb->bi_cache.c_leaves > eimax ) { + if ( slapMode & SLAP_TOOL_READONLY ) { + eifree = bdb->bi_cache.c_leaves; + } else if ( bdb->bi_cache.c_eimax && + bdb->bi_cache.c_leaves > bdb->bi_cache.c_eimax ) { eifree = bdb->bi_cache.c_minfree * 10; - if ( eifree >= eimax ) - eifree = eimax / 2; + if ( eifree >= bdb->bi_cache.c_leaves ) + eifree /= 2; } if ( !efree && !eifree ) { @@ -1065,7 +1066,7 @@ load1: int purge = 0; if ( bdb->bi_cache.c_cursize > bdb->bi_cache.c_maxsize || - bdb->bi_cache.c_leaves > bdb->bi_cache.c_eimax ) { + ( bdb->bi_cache.c_eimax && bdb->bi_cache.c_leaves > bdb->bi_cache.c_eimax )) { ldap_pvt_thread_mutex_lock( &bdb->bi_cache.c_count_mutex ); if ( !bdb->bi_cache.c_purging ) { if ( load && !( flag & ID_NOCACHE )) { @@ -1074,7 +1075,7 @@ load1: purge = 1; bdb->bi_cache.c_purging = 1; } - } else if ( bdb->bi_cache.c_leaves > bdb->bi_cache.c_eimax ) { + } else if ( bdb->bi_cache.c_eimax && bdb->bi_cache.c_leaves > bdb->bi_cache.c_eimax ) { purge = 1; bdb->bi_cache.c_purging = 1; } diff --git a/servers/slapd/back-bdb/config.c b/servers/slapd/back-bdb/config.c index 1f75f0f4e6..1228cd6903 100644 --- a/servers/slapd/back-bdb/config.c +++ b/servers/slapd/back-bdb/config.c @@ -61,12 +61,12 @@ static ConfigTable bdbcfg[] = { "DESC 'Directory for database content' " "EQUALITY caseIgnoreMatch " "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL }, - { "cachefree", "size", 2, 2, 0, ARG_UINT|ARG_OFFSET, + { "cachefree", "size", 2, 2, 0, ARG_ULONG|ARG_OFFSET, (void *)offsetof(struct bdb_info, bi_cache.c_minfree), "( OLcfgDbAt:1.11 NAME 'olcDbCacheFree' " "DESC 'Number of extra entries to free when max is reached' " "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL }, - { "cachesize", "size", 2, 2, 0, ARG_UINT|ARG_OFFSET, + { "cachesize", "size", 2, 2, 0, ARG_ULONG|ARG_OFFSET, (void *)offsetof(struct bdb_info, bi_cache.c_maxsize), "( OLcfgDbAt:1.1 NAME 'olcDbCacheSize' " "DESC 'Entry cache size in entries' " @@ -109,12 +109,12 @@ static ConfigTable bdbcfg[] = { "( OLcfgDbAt:1.5 NAME 'olcDbDirtyRead' " "DESC 'Allow reads of uncommitted data' " "SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL }, - { "dncachesize", "size", 2, 2, 0, ARG_UINT|ARG_OFFSET, + { "dncachesize", "size", 2, 2, 0, ARG_ULONG|ARG_OFFSET, (void *)offsetof(struct bdb_info, bi_cache.c_eimax), "( OLcfgDbAt:1.12 NAME 'olcDbDNcacheSize' " "DESC 'DN cache size' " "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL }, - { "idlcachesize", "size", 2, 2, 0, ARG_UINT|ARG_OFFSET, + { "idlcachesize", "size", 2, 2, 0, ARG_ULONG|ARG_OFFSET, (void *)offsetof(struct bdb_info, bi_idl_cache_max_size), "( OLcfgDbAt:1.6 NAME 'olcDbIDLcacheSize' " "DESC 'IDL cache size in IDLs' " diff --git a/servers/slapd/back-bdb/idl.c b/servers/slapd/back-bdb/idl.c index 481d9298e7..93dc87d02e 100644 --- a/servers/slapd/back-bdb/idl.c +++ b/servers/slapd/back-bdb/idl.c @@ -376,7 +376,7 @@ bdb_idl_cache_put( } bdb->bi_idl_lru_head = ee; - if ( ++bdb->bi_idl_cache_size > bdb->bi_idl_cache_max_size ) { + if ( bdb->bi_idl_cache_size >= bdb->bi_idl_cache_max_size ) { int i; ee = bdb->bi_idl_lru_tail; for ( i = 0; ee != NULL && i < 10; i++, ee = eprev ) { @@ -405,6 +405,7 @@ bdb_idl_cache_put( assert( bdb->bi_idl_lru_tail != NULL || bdb->bi_idl_lru_head == NULL ); } + bdb->bi_idl_cache_size++; ldap_pvt_thread_mutex_unlock( &bdb->bi_idl_tree_lrulock ); ldap_pvt_thread_rdwr_wunlock( &bdb->bi_idl_tree_rwlock ); } diff --git a/servers/slapd/back-bdb/init.c b/servers/slapd/back-bdb/init.c index fe480e59a9..db51f2a014 100644 --- a/servers/slapd/back-bdb/init.c +++ b/servers/slapd/back-bdb/init.c @@ -369,13 +369,10 @@ shm_retry: } #endif - /* Default dncache to 2x entrycache */ - if ( bdb->bi_cache.c_maxsize && !bdb->bi_cache.c_eimax ) { - bdb->bi_cache.c_eimax = bdb->bi_cache.c_maxsize * 2; - } - - /* dncache must be >= entrycache */ - if ( bdb->bi_cache.c_eimax < bdb->bi_cache.c_maxsize ) { + /* dncache defaults to 0 == unlimited + * must be >= entrycache + */ + if ( bdb->bi_cache.c_eimax && bdb->bi_cache.c_eimax < bdb->bi_cache.c_maxsize ) { bdb->bi_cache.c_eimax = bdb->bi_cache.c_maxsize; } diff --git a/servers/slapd/back-bdb/monitor.c b/servers/slapd/back-bdb/monitor.c index 8a2b23b778..84e2d0c338 100644 --- a/servers/slapd/back-bdb/monitor.c +++ b/servers/slapd/back-bdb/monitor.c @@ -158,17 +158,17 @@ bdb_monitor_update( a = attr_find( e->e_attrs, ad_olmBDBEntryCache ); assert( a != NULL ); bv.bv_val = buf; - bv.bv_len = snprintf( buf, sizeof( buf ), "%d", bdb->bi_cache.c_cursize ); + bv.bv_len = snprintf( buf, sizeof( buf ), "%lu", bdb->bi_cache.c_cursize ); ber_bvreplace( &a->a_vals[ 0 ], &bv ); a = attr_find( e->e_attrs, ad_olmBDBDNCache ); assert( a != NULL ); - bv.bv_len = snprintf( buf, sizeof( buf ), "%d", bdb->bi_cache.c_eiused ); + bv.bv_len = snprintf( buf, sizeof( buf ), "%lu", bdb->bi_cache.c_eiused ); ber_bvreplace( &a->a_vals[ 0 ], &bv ); a = attr_find( e->e_attrs, ad_olmBDBIDLCache ); assert( a != NULL ); - bv.bv_len = snprintf( buf, sizeof( buf ), "%d", bdb->bi_idl_cache_size ); + bv.bv_len = snprintf( buf, sizeof( buf ), "%lu", bdb->bi_idl_cache_size ); ber_bvreplace( &a->a_vals[ 0 ], &bv ); #ifdef BDB_MONITOR_IDX diff --git a/servers/slapd/config.c b/servers/slapd/config.c index 4b1ac384fa..9840780982 100644 --- a/servers/slapd/config.c +++ b/servers/slapd/config.c @@ -128,6 +128,7 @@ int config_check_vals(ConfigTable *Conf, ConfigArgs *c, int check_only ) { int rc, arg_user, arg_type, arg_syn, iarg; unsigned uiarg; long larg; + unsigned long ularg; ber_len_t barg; if(Conf->arg_type == ARG_IGNORED) { @@ -260,6 +261,16 @@ int config_check_vals(ConfigTable *Conf, ConfigArgs *c, int check_only ) { return(ARG_BAD_CONF); } break; + case ARG_ULONG: + if ( lutil_atoulx( &ularg, c->argv[1], 0 ) != 0 ) { + snprintf( c->cr_msg, sizeof( c->cr_msg ), + "<%s> unable to parse \"%s\" as unsigned long", + c->argv[0], c->argv[1] ); + Debug(LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE, "%s: %s\n", + c->log, c->cr_msg, 0); + return(ARG_BAD_CONF); + } + break; case ARG_BER_LEN_T: { unsigned long l; if ( lutil_atoulx( &l, c->argv[1], 0 ) != 0 ) { @@ -308,6 +319,7 @@ int config_check_vals(ConfigTable *Conf, ConfigArgs *c, int check_only ) { case ARG_INT: c->value_int = iarg; break; case ARG_UINT: c->value_uint = uiarg; break; case ARG_LONG: c->value_long = larg; break; + case ARG_ULONG: c->value_ulong = ularg; break; case ARG_BER_LEN_T: c->value_ber_t = barg; break; } } @@ -359,6 +371,7 @@ int config_set_vals(ConfigTable *Conf, ConfigArgs *c) { case ARG_INT: *(int*)ptr = c->value_int; break; case ARG_UINT: *(unsigned*)ptr = c->value_uint; break; case ARG_LONG: *(long*)ptr = c->value_long; break; + case ARG_ULONG: *(unsigned long*)ptr = c->value_ulong; break; case ARG_BER_LEN_T: *(ber_len_t*)ptr = c->value_ber_t; break; case ARG_STRING: { char *cc = *(char**)ptr; @@ -449,6 +462,7 @@ config_get_vals(ConfigTable *cf, ConfigArgs *c) case ARG_INT: c->value_int = *(int *)ptr; break; case ARG_UINT: c->value_uint = *(unsigned *)ptr; break; case ARG_LONG: c->value_long = *(long *)ptr; break; + case ARG_ULONG: c->value_ulong = *(unsigned long *)ptr; break; case ARG_BER_LEN_T: c->value_ber_t = *(ber_len_t *)ptr; break; case ARG_STRING: if ( *(char **)ptr ) @@ -467,6 +481,7 @@ config_get_vals(ConfigTable *cf, ConfigArgs *c) case ARG_INT: bv.bv_len = snprintf(bv.bv_val, sizeof( c->log ), "%d", c->value_int); break; case ARG_UINT: bv.bv_len = snprintf(bv.bv_val, sizeof( c->log ), "%u", c->value_uint); break; case ARG_LONG: bv.bv_len = snprintf(bv.bv_val, sizeof( c->log ), "%ld", c->value_long); break; + case ARG_ULONG: bv.bv_len = snprintf(bv.bv_val, sizeof( c->log ), "%lu", c->value_ulong); break; case ARG_BER_LEN_T: bv.bv_len = snprintf(bv.bv_val, sizeof( c->log ), "%ld", c->value_ber_t); break; case ARG_ON_OFF: bv.bv_len = snprintf(bv.bv_val, sizeof( c->log ), "%s", c->value_int ? "TRUE" : "FALSE"); break; diff --git a/servers/slapd/config.h b/servers/slapd/config.h index ca84a3c18c..99eb6b2c8e 100644 --- a/servers/slapd/config.h +++ b/servers/slapd/config.h @@ -59,6 +59,7 @@ typedef enum { #define ARG_DN 0x00007000 #define ARG_UINT 0x00008000 #define ARG_ATDESC 0x00009000 +#define ARG_ULONG 0x0000a000 #define ARGS_SYNTAX 0xffff0000 #define ARG_IGNORED 0x00080000 @@ -134,6 +135,7 @@ typedef struct config_args_s { int v_int; unsigned v_uint; long v_long; + unsigned long v_ulong; ber_len_t v_ber_t; char *v_string; struct berval v_bv; @@ -167,6 +169,7 @@ typedef struct config_args_s { #define value_int values.v_int #define value_uint values.v_uint #define value_long values.v_long +#define value_ulong values.v_ulong #define value_ber_t values.v_ber_t #define value_string values.v_string #define value_bv values.v_bv -- 2.39.5