src/com
by Mark Reynolds
src/com/netscape/admin/dirserv/DSContentPage.java | 1 +
src/com/netscape/admin/dirserv/panel/BlankPanel.java | 2 +-
src/com/netscape/admin/dirserv/panel/PasswordPolicyPanel.java | 5 ++---
3 files changed, 4 insertions(+), 4 deletions(-)
New commits:
commit 21150c90a8745907e1979b111652d0f58a425535
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Fri Aug 22 16:47:28 2014 -0400
Ticket 96 - Window too large for Manage password policy
Bug Description: The password policy panel can very very tall for lower
resolution displays.
Fix Description: Set the prefered size of the this panel to something
reasonable and let the scrollbar handle the rest.
https://fedorahosted.org/389/ticket/96
Reviewed by: rmeggins(Thanks!)
diff --git a/src/com/netscape/admin/dirserv/DSContentPage.java b/src/com/netscape/admin/dirserv/DSContentPage.java
index dc14070..6de20a7 100644
--- a/src/com/netscape/admin/dirserv/DSContentPage.java
+++ b/src/com/netscape/admin/dirserv/DSContentPage.java
@@ -2053,6 +2053,7 @@ implements IPage,
if ( dn != null) {
BlankPanel child = new BlankPanel(_resourceModel);
child.setLayout(new BorderLayout());
+ child.setPreferredSize(new Dimension(500, 500));
PasswordPolicyTabbedDialog tabchild =
new PasswordPolicyTabbedDialog(_resourceModel, dn, type);
diff --git a/src/com/netscape/admin/dirserv/panel/BlankPanel.java b/src/com/netscape/admin/dirserv/panel/BlankPanel.java
index e7f3d72..e5d39fc 100644
--- a/src/com/netscape/admin/dirserv/panel/BlankPanel.java
+++ b/src/com/netscape/admin/dirserv/panel/BlankPanel.java
@@ -143,7 +143,7 @@ public class BlankPanel extends JPanel
gbc.anchor = gbc.NORTHWEST;
if ( scroll ) {
JScrollPane jscroll = new JScrollPane( _myPanel );
- jscroll.setBorder( new EmptyBorder( 0, 0, 0, 0 ) );
+ jscroll.setBorder( new EmptyBorder( 0, 0, 0, 0 ) );
add( jscroll, gbc );
} else {
add( _myPanel, gbc );
diff --git a/src/com/netscape/admin/dirserv/panel/PasswordPolicyPanel.java b/src/com/netscape/admin/dirserv/panel/PasswordPolicyPanel.java
index 8089b49..7d3e84b 100644
--- a/src/com/netscape/admin/dirserv/panel/PasswordPolicyPanel.java
+++ b/src/com/netscape/admin/dirserv/panel/PasswordPolicyPanel.java
@@ -79,15 +79,14 @@ public class PasswordPolicyPanel extends BlankPanel {
return;
}
_spec_exists = fineGrainedPolicyPresent();
-
- _myPanel.setLayout(new GridBagLayout());
+ _myPanel.setLayout(new GridBagLayout());
if (_mode != SERVER) {
createFineGrainedToggleArea((Container)_myPanel);
} else {
createFineGrainedPolicyArea((Container)_myPanel);
}
-
+
createChangeArea((Container)_myPanel);
createExpirationArea((Container)_myPanel);
createSyntaxArea((Container)_myPanel);
9 years, 8 months
Branch '389-ds-base-1.3.2' - ldap/servers
by Noriko Hosoi
ldap/servers/plugins/replication/cl5_api.c | 31 ++-
ldap/servers/slapd/back-ldbm/back-ldbm.h | 2
ldap/servers/slapd/back-ldbm/cache.c | 237 ++++++++++++++-----------
ldap/servers/slapd/back-ldbm/ldbm_add.c | 75 ++-----
ldap/servers/slapd/back-ldbm/ldbm_delete.c | 220 ++++++++---------------
ldap/servers/slapd/back-ldbm/ldbm_modify.c | 90 ++++-----
ldap/servers/slapd/back-ldbm/ldbm_modrdn.c | 153 +++++-----------
ldap/servers/slapd/back-ldbm/parents.c | 4
ldap/servers/slapd/back-ldbm/proto-back-ldbm.h | 5
9 files changed, 384 insertions(+), 433 deletions(-)
New commits:
commit d9c8b1fe47e8ce708fa3cbeddbefa1916f1bf669
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Tue Aug 19 14:42:52 2014 -0700
Ticket #47834 - Tombstone_to_glue: if parents are also converted to glue, the target entry's DN must be adjusted.
Bug Description: Test case to verify the problem crashed the server.
Fix Description:
1. Clean up entry cache related code
1-1. Changing cache log reentrant to avoid self deadlock.
1-2. Introducing cache_is_in_cache to get rid of local variables in
ldap_back_{add,delete,modify,modrdn}.
2. ldap_back_{add,delete,modify,modrdn}
2-1. As described in 1-2, removed [a-z]*_in_cache local variables.
2-2. In the deadlock retry loop, entries were duplicated by backentry_
dup after CACHE_REMOVE'd and CACHE_RETURN'ed. At the moment, the
entry could be already freed. Changed to create a duplicated
entry before calling CACHE_REMOVE and CACHE_RETURN.
3. _cl5NewDBFile (replication/cl5_api.c): When a leftover semaphore is
found, _cl5NewDBFile removes it and creates it, but it rarely fails
to delete and it causes the server restart fail. Adding a message
to remove such a leftover semaphore by ipcrm.
https://fedorahosted.org/389/ticket/47834
Reviewed by mreynolds(a)redhat.com (Thank you, Mark!!)
(cherry picked from commit 6333936da2c4287e96b36fecc24a4c62da5a8ea2)
diff --git a/ldap/servers/plugins/replication/cl5_api.c b/ldap/servers/plugins/replication/cl5_api.c
index 85727f9..42e52ae 100644
--- a/ldap/servers/plugins/replication/cl5_api.c
+++ b/ldap/servers/plugins/replication/cl5_api.c
@@ -5784,7 +5784,7 @@ static int _cl5DBOpenFileByReplicaName (const char *replName, const char *replGe
if (checkDups)
{
PR_Lock (s_cl5Desc.fileLock);
- file_name = _cl5MakeFileName (replName, replGen);
+ file_name = _cl5MakeFileName (replName, replGen);
tmpObj = objset_find (s_cl5Desc.dbFiles, _cl5CompareDBFile, file_name);
slapi_ch_free((void **)&file_name);
if (tmpObj) /* this file already exist */
@@ -5859,10 +5859,10 @@ done:;
if (checkDups)
{
- PR_Unlock (s_cl5Desc.fileLock);
- }
+ PR_Unlock (s_cl5Desc.fileLock);
+ }
- return rc;
+ return rc;
}
/* adds file to the db file list */
@@ -6026,7 +6026,14 @@ out:
* and re-create it.
*/
if (PR_GetError() == PR_FILE_EXISTS_ERROR) {
+ PRErrorCode prerr;
PR_DeleteSemaphore((*dbFile)->semaName);
+ prerr = PR_GetError();
+ if (PR_SUCCESS != prerr) {
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl,
+ "_cl5NewDBFile: PR_DeleteSemaphore: %s; NSPR error - %d\n",
+ (*dbFile)->semaName ? (*dbFile)->semaName : "(nil)", prerr);
+ }
(*dbFile)->sema = PR_OpenSemaphore((*dbFile)->semaName,
PR_SEM_CREATE | PR_SEM_EXCL, 0666,
s_cl5Desc.dbConfig.maxConcurrentWrites );
@@ -6036,9 +6043,19 @@ out:
* we should just error out. */
if ((*dbFile)->sema == NULL )
{
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl,
- "_cl5NewDBFile: failed to create semaphore %s; NSPR error - %d\n",
- (*dbFile)->semaName ? (*dbFile)->semaName : "(nil)", PR_GetError());
+ PRErrorCode prerr = PR_GetError();
+ if (PR_FILE_EXISTS_ERROR == prerr) {
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl,
+ "_cl5NewDBFile: PR_OpenSemaphore: %s; sema: 0x%p, NSPR error - %d\n",
+ (*dbFile)->semaName ? (*dbFile)->semaName : "(nil)", (*dbFile)->sema, prerr);
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl,
+ " : Leftover semaphores may exist. "
+ "Run \"ipcs -s\", and remove them with \"ipcrm -s <SEMID>\" if any\n");
+ } else {
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl,
+ "_cl5NewDBFile: failed to create semaphore %s; NSPR error - %d\n",
+ (*dbFile)->semaName ? (*dbFile)->semaName : "(nil)", prerr);
+ }
rc = CL5_SYSTEM_ERROR;
goto done;
}
diff --git a/ldap/servers/slapd/back-ldbm/back-ldbm.h b/ldap/servers/slapd/back-ldbm/back-ldbm.h
index bd84e0f..938d261 100644
--- a/ldap/servers/slapd/back-ldbm/back-ldbm.h
+++ b/ldap/servers/slapd/back-ldbm/back-ldbm.h
@@ -403,7 +403,7 @@ struct cache {
Slapi_Counter *c_tries;
struct backcommon *c_lruhead; /* add entries here */
struct backcommon *c_lrutail; /* remove entries here */
- PRLock *c_mutex; /* lock for cache operations */
+ PRMonitor *c_mutex; /* lock for cache operations */
PRLock *c_emutexalloc_mutex;
};
diff --git a/ldap/servers/slapd/back-ldbm/cache.c b/ldap/servers/slapd/back-ldbm/cache.c
index 0732415..a98cf0c 100644
--- a/ldap/servers/slapd/back-ldbm/cache.c
+++ b/ldap/servers/slapd/back-ldbm/cache.c
@@ -544,10 +544,9 @@ int cache_init(struct cache *cache, size_t maxsize, long maxentries, int type)
cache->c_lruhead = cache->c_lrutail = NULL;
cache_make_hashes(cache, type);
- if (((cache->c_mutex = PR_NewLock()) == NULL) ||
- ((cache->c_emutexalloc_mutex = PR_NewLock()) == NULL)) {
- LDAPDebug(LDAP_DEBUG_ANY, "ldbm: cache_init: PR_NewLock failed\n",
- 0, 0, 0);
+ if (((cache->c_mutex = PR_NewMonitor()) == NULL) ||
+ ((cache->c_emutexalloc_mutex = PR_NewLock()) == NULL)) {
+ LDAPDebug0Args(LDAP_DEBUG_ANY, "ldbm: cache_init: PR_NewMonitor failed\n");
return 0;
}
LDAPDebug(LDAP_DEBUG_TRACE, "<= cache_init\n", 0, 0, 0);
@@ -634,13 +633,13 @@ static void entrycache_clear_int(struct cache *cache)
void cache_clear(struct cache *cache, int type)
{
- PR_Lock(cache->c_mutex);
+ cache_lock(cache);
if (CACHE_TYPE_ENTRY == type) {
entrycache_clear_int(cache);
} else if (CACHE_TYPE_DN == type) {
dncache_clear_int(cache);
}
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
}
static void erase_cache(struct cache *cache, int type)
@@ -664,7 +663,7 @@ void cache_destroy_please(struct cache *cache, int type)
slapi_counter_destroy(&cache->c_cursize);
slapi_counter_destroy(&cache->c_hits);
slapi_counter_destroy(&cache->c_tries);
- PR_DestroyLock(cache->c_mutex);
+ PR_DestroyMonitor(cache->c_mutex);
PR_DestroyLock(cache->c_emutexalloc_mutex);
}
@@ -688,7 +687,7 @@ static void entrycache_set_max_size(struct cache *cache, size_t bytes)
"WARNING -- Minimum cache size is %lu -- rounding up\n",
MINCACHESIZE, 0, 0);
}
- PR_Lock(cache->c_mutex);
+ cache_lock(cache);
cache->c_maxsize = bytes;
LOG("entry cache size set to %lu\n", bytes, 0, 0);
/* check for full cache, and clear out if necessary */
@@ -707,7 +706,7 @@ static void entrycache_set_max_size(struct cache *cache, size_t bytes)
erase_cache(cache, CACHE_TYPE_ENTRY);
cache_make_hashes(cache, CACHE_TYPE_ENTRY);
}
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
if (! dblayer_is_cachesize_sane(&bytes)) {
LDAPDebug(LDAP_DEBUG_ANY,
"WARNING -- Possible CONFIGURATION ERROR -- cachesize "
@@ -725,7 +724,7 @@ void cache_set_max_entries(struct cache *cache, long entries)
* was given in # entries instead of memory footprint. hopefully,
* we can eventually drop this.
*/
- PR_Lock(cache->c_mutex);
+ cache_lock(cache);
cache->c_maxentries = entries;
if (entries >= 0) {
LOG("entry cache entry-limit set to %lu\n", entries, 0, 0);
@@ -736,7 +735,7 @@ void cache_set_max_entries(struct cache *cache, long entries)
/* check for full cache, and clear out if necessary */
if (CACHE_FULL(cache))
eflush = entrycache_flush(cache);
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
while (eflush)
{
eflushtemp = BACK_LRU_NEXT(eflush, struct backentry *);
@@ -749,9 +748,9 @@ size_t cache_get_max_size(struct cache *cache)
{
size_t n = 0;
- PR_Lock(cache->c_mutex);
+ cache_lock(cache);
n = cache->c_maxsize;
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
return n;
}
@@ -759,9 +758,9 @@ long cache_get_max_entries(struct cache *cache)
{
long n;
- PR_Lock(cache->c_mutex);
+ cache_lock(cache);
n = cache->c_maxentries;
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
return n;
}
@@ -787,14 +786,14 @@ void cache_get_stats(struct cache *cache, PRUint64 *hits, PRUint64 *tries,
long *nentries, long *maxentries,
size_t *size, size_t *maxsize)
{
- PR_Lock(cache->c_mutex);
+ cache_lock(cache);
if (hits) *hits = slapi_counter_get_value(cache->c_hits);
if (tries) *tries = slapi_counter_get_value(cache->c_tries);
if (nentries) *nentries = cache->c_curentries;
if (maxentries) *maxentries = cache->c_maxentries;
if (size) *size = slapi_counter_get_value(cache->c_cursize);
if (maxsize) *maxsize = cache->c_maxsize;
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
}
void cache_debug_hash(struct cache *cache, char **out)
@@ -805,7 +804,7 @@ void cache_debug_hash(struct cache *cache, char **out)
Hashtable *ht = NULL;
char *name = "unknown";
- PR_Lock(cache->c_mutex);
+ cache_lock(cache);
*out = (char *)slapi_ch_malloc(1024);
**out = 0;
@@ -841,7 +840,7 @@ void cache_debug_hash(struct cache *cache, char **out)
sprintf(*out + strlen(*out), "%d[%d] ", j, slot_stats[j]);
slapi_ch_free((void **)&slot_stats);
}
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
}
@@ -947,14 +946,14 @@ int cache_remove(struct cache *cache, void *ptr)
}
e = (struct backcommon *)ptr;
- PR_Lock(cache->c_mutex);
+ cache_lock(cache);
if (CACHE_TYPE_ENTRY == e->ep_type) {
ASSERT(e->ep_refcnt > 0);
ret = entrycache_remove_int(cache, (struct backentry *)e);
} else if (CACHE_TYPE_DN == e->ep_type) {
ret = dncache_remove_int(cache, (struct backdn *)e);
}
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
return ret;
}
@@ -1014,7 +1013,7 @@ static int entrycache_replace(struct cache *cache, struct backentry *olde,
#endif
newndn = slapi_sdn_get_ndn(backentry_get_sdn(newe));
entry_size = cache_entry_size(newe);
- PR_Lock(cache->c_mutex);
+ cache_lock(cache);
/*
* First, remove the old entry from all the hashtables.
@@ -1034,7 +1033,7 @@ static int entrycache_replace(struct cache *cache, struct backentry *olde,
}
/* If fails, we have to make sure the both entires are removed from the cache,
* otherwise, we have no idea what's left in the cache or not... */
- if (!entry_same_dn(newe, (void *)oldndn) && (newe->ep_state & ENTRY_STATE_NOTINCACHE) == 0) {
+ if (cache_is_in_cache(cache, newe)) {
/* if we're doing a modrdn or turning an entry to a tombstone,
* the new entry can be in the dn table already, so we need to remove that too.
*/
@@ -1042,6 +1041,7 @@ static int entrycache_replace(struct cache *cache, struct backentry *olde,
{
slapi_counter_subtract(cache->c_cursize, newe->ep_size);
cache->c_curentries--;
+ newe->ep_refcnt--;
LOG("entry cache replace remove entry size %lu\n", newe->ep_size, 0, 0);
}
}
@@ -1064,7 +1064,7 @@ static int entrycache_replace(struct cache *cache, struct backentry *olde,
LOG("entry cache replace (%s): cache index tables out of sync - found dn [%d] id [%d]\n",
oldndn, found_in_dn, found_in_id);
#endif
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
return 1;
}
}
@@ -1073,32 +1073,32 @@ static int entrycache_replace(struct cache *cache, struct backentry *olde,
* tested enough that we believe it works.)
*/
if (!add_hash(cache->c_dntable, (void *)newndn, strlen(newndn), newe, (void **)&alte)) {
- LOG("entry cache replace (%s): can't add to dn table (returned %s)\n",
- newndn, alte?slapi_entry_get_dn(alte->ep_entry):"none", 0);
- PR_Unlock(cache->c_mutex);
- return 1;
+ LOG("entry cache replace (%s): can't add to dn table (returned %s)\n",
+ newndn, alte?slapi_entry_get_dn(alte->ep_entry):"none", 0);
+ cache_lock(cache);
+ return 1;
}
if (!add_hash(cache->c_idtable, &(newe->ep_id), sizeof(ID), newe, (void **)&alte)) {
- LOG("entry cache replace (%s): can't add to id table (returned %s)\n",
- newndn, alte?slapi_entry_get_dn(alte->ep_entry):"none", 0);
- if(remove_hash(cache->c_dntable, (void *)newndn, strlen(newndn)) == 0){
- LOG("entry cache replace: failed to remove dn table\n", 0, 0, 0);
- }
- PR_Unlock(cache->c_mutex);
- return 1;
+ LOG("entry cache replace (%s): can't add to id table (returned %s)\n",
+ newndn, alte?slapi_entry_get_dn(alte->ep_entry):"none", 0);
+ if(remove_hash(cache->c_dntable, (void *)newndn, strlen(newndn)) == 0){
+ LOG("entry cache replace: failed to remove dn table\n", 0, 0, 0);
+ }
+ cache_unlock(cache);
+ return 1;
}
#ifdef UUIDCACHE_ON
if (newuuid && !add_hash(cache->c_uuidtable, (void *)newuuid, strlen(newuuid),
newe, NULL)) {
- LOG("entry cache replace: can't add uuid\n", 0, 0, 0);
- if(remove_hash(cache->c_dntable, (void *)newndn, strlen(newndn)) == 0){
- LOG("entry cache replace: failed to remove dn table(uuid cache)\n", 0, 0, 0);
- }
- if(remove_hash(cache->c_idtable, &(newe->ep_id), sizeof(ID)) == 0){
- LOG("entry cache replace: failed to remove id table(uuid cache)\n", 0, 0, 0);
- }
- PR_Unlock(cache->c_mutex);
- return 1;
+ LOG("entry cache replace: can't add uuid\n", 0, 0, 0);
+ if(remove_hash(cache->c_dntable, (void *)newndn, strlen(newndn)) == 0){
+ LOG("entry cache replace: failed to remove dn table(uuid cache)\n", 0, 0, 0);
+ }
+ if(remove_hash(cache->c_idtable, &(newe->ep_id), sizeof(ID)) == 0){
+ LOG("entry cache replace: failed to remove id table(uuid cache)\n", 0, 0, 0);
+ }
+ cache_unlock(cache);
+ return 1;
}
#endif
/* adjust cache meta info */
@@ -1110,7 +1110,7 @@ static int entrycache_replace(struct cache *cache, struct backentry *olde,
slapi_counter_subtract(cache->c_cursize, olde->ep_size - newe->ep_size);
}
newe->ep_state = 0;
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
LOG("<= entrycache_replace OK, cache size now %lu cache count now %ld\n",
slapi_counter_get_value(cache->c_cursize), cache->c_curentries, 0);
return 0;
@@ -1144,10 +1144,14 @@ entrycache_return(struct cache *cache, struct backentry **bep)
struct backentry *e;
e = *bep;
+ if (!e) {
+ LDAPDebug0Args(LDAP_DEBUG_ANY, "entrycache_return e is NULL\n");
+ return;
+ }
LOG("=> entrycache_return (%s) entry count: %d, entry in cache:%ld\n",
backentry_get_ndn(e), e->ep_refcnt, cache->c_curentries);
- PR_Lock(cache->c_mutex);
+ cache_lock(cache);
if (e->ep_state & ENTRY_STATE_NOTINCACHE)
{
backentry_free(bep);
@@ -1166,7 +1170,7 @@ entrycache_return(struct cache *cache, struct backentry **bep)
}
}
}
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
while (eflush)
{
eflushtemp = BACK_LRU_NEXT(eflush, struct backentry *);
@@ -1185,22 +1189,22 @@ struct backentry *cache_find_dn(struct cache *cache, const char *dn, unsigned lo
LOG("=> cache_find_dn (%s)\n", dn, 0, 0);
/*entry normalized by caller (dn2entry.c) */
- PR_Lock(cache->c_mutex);
+ cache_lock(cache);
if (find_hash(cache->c_dntable, (void *)dn, ndnlen, (void **)&e)) {
/* need to check entry state */
if (e->ep_state != 0) {
/* entry is deleted or not fully created yet */
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
LOG("<= cache_find_dn (NOT FOUND)\n", 0, 0, 0);
return NULL;
}
if (e->ep_refcnt == 0)
lru_delete(cache, (void *)e);
e->ep_refcnt++;
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
slapi_counter_increment(cache->c_hits);
} else {
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
}
slapi_counter_increment(cache->c_tries);
@@ -1216,22 +1220,22 @@ struct backentry *cache_find_id(struct cache *cache, ID id)
LOG("=> cache_find_id (%lu)\n", (u_long)id, 0, 0);
- PR_Lock(cache->c_mutex);
+ cache_lock(cache);
if (find_hash(cache->c_idtable, &id, sizeof(ID), (void **)&e)) {
/* need to check entry state */
if (e->ep_state != 0) {
/* entry is deleted or not fully created yet */
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
LOG("<= cache_find_id (NOT FOUND)\n", 0, 0, 0);
return NULL;
}
if (e->ep_refcnt == 0)
lru_delete(cache, (void *)e);
e->ep_refcnt++;
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
slapi_counter_increment(cache->c_hits);
} else {
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
}
slapi_counter_increment(cache->c_tries);
@@ -1247,22 +1251,22 @@ struct backentry *cache_find_uuid(struct cache *cache, const char *uuid)
LOG("=> cache_find_uuid (%s)\n", uuid, 0, 0);
- PR_Lock(cache->c_mutex);
+ cache_lock(cache);
if (find_hash(cache->c_uuidtable, uuid, strlen(uuid), (void **)&e)) {
/* need to check entry state */
if (e->ep_state != 0) {
/* entry is deleted or not fully created yet */
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
LOG("<= cache_find_uuid (NOT FOUND)\n", 0, 0, 0);
return NULL;
}
if (e->ep_refcnt == 0)
lru_delete(cache, (void *)e);
e->ep_refcnt++;
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
slapi_counter_increment(cache->c_hits);
} else {
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
}
slapi_counter_increment(cache->c_tries);
@@ -1299,7 +1303,7 @@ entrycache_add_int(struct cache *cache, struct backentry *e, int state,
entry_size = e->ep_size;
}
- PR_Lock(cache->c_mutex);
+ cache_lock(cache);
if (! add_hash(cache->c_dntable, (void *)ndn, strlen(ndn), e,
(void **)&my_alt)) {
LOG("entry \"%s\" already in dn cache\n", ndn, 0, 0);
@@ -1334,7 +1338,7 @@ entrycache_add_int(struct cache *cache, struct backentry *e, int state,
* to prevent that the caller accidentally thinks the existing
* entry is not the same one the caller has and releases it.
*/
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
return 1;
}
}
@@ -1344,7 +1348,7 @@ entrycache_add_int(struct cache *cache, struct backentry *e, int state,
{
LOG("the entry %s is reserved (ep_state: 0x%x, state: 0x%x)\n", ndn, e->ep_state, state);
e->ep_state |= ENTRY_STATE_NOTINCACHE;
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
return -1;
}
else if (state != 0)
@@ -1352,7 +1356,7 @@ entrycache_add_int(struct cache *cache, struct backentry *e, int state,
LOG("the entry %s already exists. cannot reserve it. (ep_state: 0x%x, state: 0x%x)\n",
ndn, e->ep_state, state);
e->ep_state |= ENTRY_STATE_NOTINCACHE;
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
return -1;
}
else
@@ -1364,12 +1368,14 @@ entrycache_add_int(struct cache *cache, struct backentry *e, int state,
(*alt)->ep_refcnt++;
LOG("the entry %s already exists. returning existing entry %s (state: 0x%x)\n",
ndn, backentry_get_ndn(my_alt), state);
+ cache_unlock(cache);
+ return 1;
} else {
LOG("the entry %s already exists. Not returning existing entry %s (state: 0x%x)\n",
ndn, backentry_get_ndn(my_alt), state);
+ cache_unlock(cache);
+ return -1;
}
- PR_Unlock(cache->c_mutex);
- return 1;
}
}
}
@@ -1399,14 +1405,14 @@ entrycache_add_int(struct cache *cache, struct backentry *e, int state,
* fine (i think).
*/
LOG("<= entrycache_add_int (ignoring)\n", 0, 0, 0);
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
return 0;
}
if(remove_hash(cache->c_dntable, (void *)ndn, strlen(ndn)) == 0){
LOG("entrycache_add_int: failed to remove %s from dn table\n", 0, 0, 0);
}
e->ep_state |= ENTRY_STATE_NOTINCACHE;
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
LOG("entrycache_add_int: failed to add %s to cache (ep_state: %x, already_in: %d)\n",
ndn, e->ep_state, already_in);
return -1;
@@ -1425,7 +1431,7 @@ entrycache_add_int(struct cache *cache, struct backentry *e, int state,
LOG("entrycache_add_int: failed to remove id table(uuid cache)\n", 0, 0, 0);
}
e->ep_state |= ENTRY_STATE_NOTINCACHE;
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
return -1;
}
}
@@ -1450,7 +1456,7 @@ entrycache_add_int(struct cache *cache, struct backentry *e, int state,
if (CACHE_FULL(cache))
eflush = entrycache_flush(cache);
}
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
while (eflush)
{
@@ -1502,11 +1508,11 @@ int cache_add_tentative(struct cache *cache, struct backentry *e,
}
void cache_lock(struct cache *cache)
{
- PR_Lock(cache->c_mutex);
+ PR_EnterMonitor(cache->c_mutex);
}
void cache_unlock(struct cache *cache)
{
- PR_Unlock(cache->c_mutex);
+ PR_ExitMonitor(cache->c_mutex);
}
/* locks an entry so that it can be modified (you should have gotten the
@@ -1540,14 +1546,14 @@ int cache_lock_entry(struct cache *cache, struct backentry *e)
PR_EnterMonitor(e->ep_mutexp);
/* make sure entry hasn't been deleted now */
- PR_Lock(cache->c_mutex);
+ cache_lock(cache);
if (e->ep_state & (ENTRY_STATE_DELETED|ENTRY_STATE_NOTINCACHE)) {
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
PR_ExitMonitor(e->ep_mutexp);
LOG("<= cache_lock_entry (DELETED)\n", 0, 0, 0);
return RETRY_CACHE_LOCK;
}
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
LOG("<= cache_lock_entry (FOUND)\n", 0, 0, 0);
return 0;
@@ -1613,7 +1619,7 @@ dncache_set_max_size(struct cache *cache, size_t bytes)
"WARNING -- Minimum cache size is %lu -- rounding up\n",
MINCACHESIZE, 0, 0);
}
- PR_Lock(cache->c_mutex);
+ cache_lock(cache);
cache->c_maxsize = bytes;
LOG("entry cache size set to %lu\n", bytes, 0, 0);
/* check for full cache, and clear out if necessary */
@@ -1633,7 +1639,7 @@ dncache_set_max_size(struct cache *cache, size_t bytes)
erase_cache(cache, CACHE_TYPE_DN);
cache_make_hashes(cache, CACHE_TYPE_DN);
}
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
if (! dblayer_is_cachesize_sane(&bytes)) {
LDAPDebug1Arg(LDAP_DEBUG_ANY,
"WARNING -- Possible CONFIGURATION ERROR -- cachesize "
@@ -1697,7 +1703,7 @@ dncache_return(struct cache *cache, struct backdn **bdn)
LOG("=> dncache_return (%s) reference count: %d, dn in cache:%ld\n",
slapi_sdn_get_dn((*bdn)->dn_sdn), (*bdn)->ep_refcnt, cache->c_curentries);
- PR_Lock(cache->c_mutex);
+ cache_lock(cache);
if ((*bdn)->ep_state & ENTRY_STATE_NOTINCACHE)
{
backdn_free(bdn);
@@ -1717,7 +1723,7 @@ dncache_return(struct cache *cache, struct backdn **bdn)
}
}
}
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
while (dnflush)
{
dnflushtemp = BACK_LRU_NEXT(dnflush, struct backdn *);
@@ -1738,22 +1744,22 @@ dncache_find_id(struct cache *cache, ID id)
LOG("=> dncache_find_id (%lu)\n", (u_long)id, 0, 0);
- PR_Lock(cache->c_mutex);
+ cache_lock(cache);
if (find_hash(cache->c_idtable, &id, sizeof(ID), (void **)&bdn)) {
/* need to check entry state */
if (bdn->ep_state != 0) {
/* entry is deleted or not fully created yet */
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
LOG("<= dncache_find_id (NOT FOUND)\n", 0, 0, 0);
return NULL;
}
if (bdn->ep_refcnt == 0)
lru_delete(cache, (void *)bdn);
bdn->ep_refcnt++;
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
slapi_counter_increment(cache->c_hits);
} else {
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
}
slapi_counter_increment(cache->c_tries);
@@ -1778,7 +1784,7 @@ dncache_add_int(struct cache *cache, struct backdn *bdn, int state,
LOG("=> dncache_add_int( \"%s\", %ld )\n", slapi_sdn_get_dn(bdn->dn_sdn),
bdn->ep_id, 0);
- PR_Lock(cache->c_mutex);
+ cache_lock(cache);
if (! add_hash(cache->c_idtable, &(bdn->ep_id), sizeof(ID), bdn,
(void **)&my_alt)) {
@@ -1813,7 +1819,7 @@ dncache_add_int(struct cache *cache, struct backdn *bdn, int state,
* to prevent that the caller accidentally thinks the existing
* entry is not the same one the caller has and releases it.
*/
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
return 1;
}
}
@@ -1823,14 +1829,14 @@ dncache_add_int(struct cache *cache, struct backdn *bdn, int state,
{
LOG("the entry is reserved\n", 0, 0, 0);
bdn->ep_state |= ENTRY_STATE_NOTINCACHE;
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
return -1;
}
else if (state != 0)
{
LOG("the entry already exists. cannot reserve it.\n", 0, 0, 0);
bdn->ep_state |= ENTRY_STATE_NOTINCACHE;
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
return -1;
}
else
@@ -1841,7 +1847,7 @@ dncache_add_int(struct cache *cache, struct backdn *bdn, int state,
lru_delete(cache, (void *)*alt);
(*alt)->ep_refcnt++;
}
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
return 1;
}
}
@@ -1870,7 +1876,7 @@ dncache_add_int(struct cache *cache, struct backdn *bdn, int state,
dnflush = dncache_flush(cache);
}
}
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
while (dnflush)
{
@@ -1898,7 +1904,7 @@ dncache_replace(struct cache *cache, struct backdn *olddn, struct backdn *newdn)
* where the entry isn't in all the table yet, so we don't care if any
* of these return errors.
*/
- PR_Lock(cache->c_mutex);
+ cache_lock(cache);
/*
* First, remove the old entry from the hashtable.
@@ -1910,7 +1916,7 @@ dncache_replace(struct cache *cache, struct backdn *olddn, struct backdn *newdn)
found = remove_hash(cache->c_idtable, &(olddn->ep_id), sizeof(ID));
if (!found) {
LOG("dn cache replace: cache index tables out of sync\n", 0, 0, 0);
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
return 1;
}
}
@@ -1921,7 +1927,7 @@ dncache_replace(struct cache *cache, struct backdn *olddn, struct backdn *newdn)
*/
if (!add_hash(cache->c_idtable, &(newdn->ep_id), sizeof(ID), newdn, NULL)) {
LOG("dn cache replace: can't add id\n", 0, 0, 0);
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
return 1;
}
/* adjust cache meta info */
@@ -1936,7 +1942,7 @@ dncache_replace(struct cache *cache, struct backdn *olddn, struct backdn *newdn)
}
olddn->ep_state = ENTRY_STATE_DELETED;
newdn->ep_state = 0;
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
LOG("<= dncache_replace OK, cache size now %lu cache count now %ld\n",
slapi_counter_get_value(cache->c_cursize), cache->c_curentries, 0);
return 0;
@@ -2022,23 +2028,24 @@ dn_lru_verify(struct cache *cache, struct backdn *dn, int in)
#ifdef CACHE_DEBUG
void
-check_entry_cache(struct cache *cache, struct backentry *e, int in_cache)
+check_entry_cache(struct cache *cache, struct backentry *e)
{
Slapi_DN *sdn = slapi_entry_get_sdn(e->ep_entry);
struct backentry *debug_e = cache_find_dn(cache,
slapi_sdn_get_dn(sdn),
slapi_sdn_get_ndn_len(sdn));
+ in_cache = cache_is_in_cache(cache, (void *)e);
if (in_cache) {
if (debug_e) { /* e is in cache */
CACHE_RETURN(cache, &debug_e);
if ((e != debug_e) && !(e->ep_state & ENTRY_STATE_DELETED)) {
- slapi_log_error(SLAPI_LOG_FATAL, "ldbm_back_delete",
+ slapi_log_error(SLAPI_LOG_FATAL, "check_entry_cache",
"entry 0x%p is not in dn cache but 0x%p having the same dn %s is "
"although in_cache flag is set!!!\n",
e, debug_e, slapi_sdn_get_dn(sdn));
}
} else if (!(e->ep_state & ENTRY_STATE_DELETED)) {
- slapi_log_error(SLAPI_LOG_FATAL, "ldbm_back_delete",
+ slapi_log_error(SLAPI_LOG_FATAL, "check_entry_cache",
"%s (id %d) is not in dn cache although in_cache flag is set!!!\n",
slapi_sdn_get_dn(sdn), e->ep_id);
}
@@ -2046,13 +2053,13 @@ check_entry_cache(struct cache *cache, struct backentry *e, int in_cache)
if (debug_e) { /* e is in cache */
CACHE_RETURN(cache, &debug_e);
if ((e != debug_e) && !(e->ep_state & ENTRY_STATE_DELETED)) {
- slapi_log_error(SLAPI_LOG_FATAL, "ldbm_back_delete",
+ slapi_log_error(SLAPI_LOG_FATAL, "check_entry_cache",
"entry 0x%p is not in id cache but 0x%p having the same id %d is "
"although in_cache flag is set!!!\n",
e, debug_e, e->ep_id);
}
} else {
- slapi_log_error(SLAPI_LOG_CACHE, "ldbm_back_delete",
+ slapi_log_error(SLAPI_LOG_CACHE, "check_entry_cache",
"%s (id %d) is not in id cache although in_cache flag is set!!!\n",
slapi_sdn_get_dn(sdn), e->ep_id);
}
@@ -2060,7 +2067,7 @@ check_entry_cache(struct cache *cache, struct backentry *e, int in_cache)
if (debug_e) { /* e is in cache */
CACHE_RETURN(cache, &debug_e);
if (e == debug_e) {
- slapi_log_error(SLAPI_LOG_FATAL, "ldbm_back_delete",
+ slapi_log_error(SLAPI_LOG_FATAL, "check_entry_cache",
"%s (id %d) is in dn cache although in_cache flag is not set!!!\n",
slapi_sdn_get_dn(sdn), e->ep_id);
}
@@ -2069,7 +2076,7 @@ check_entry_cache(struct cache *cache, struct backentry *e, int in_cache)
if (debug_e) { /* e is in cache: bad */
CACHE_RETURN(cache, &debug_e);
if (e == debug_e) {
- slapi_log_error(SLAPI_LOG_CACHE, "ldbm_back_delete",
+ slapi_log_error(SLAPI_LOG_CACHE, "check_entry_cache",
"%s (id %d) is in id cache although in_cache flag is not set!!!\n",
slapi_sdn_get_dn(sdn), e->ep_id);
}
@@ -2077,3 +2084,35 @@ check_entry_cache(struct cache *cache, struct backentry *e, int in_cache)
}
}
#endif
+
+int
+cache_has_otherref(struct cache *cache, void *ptr)
+{
+ struct backcommon *bep;
+ int hasref = 0;
+
+ if (NULL == ptr) {
+ return hasref;
+ }
+ bep = (struct backcommon *)ptr;
+ /* slows down too much? PR_Lock(cache->c_mutex); */
+ hasref = bep->ep_refcnt;
+ /* PR_Unlock(cache->c_mutex); */
+ return (hasref>1)?1:0;
+}
+
+int
+cache_is_in_cache(struct cache *cache, void *ptr)
+{
+ struct backcommon *bep;
+ int in_cache = 0;
+
+ if (NULL == ptr) {
+ return in_cache;
+ }
+ bep = (struct backcommon *)ptr;
+ /* slows down too much? PR_Lock(cache->c_mutex); */
+ in_cache = (bep->ep_state & (ENTRY_STATE_DELETED|ENTRY_STATE_NOTINCACHE))?0:1;
+ /* PR_Unlock(cache->c_mutex); */
+ return in_cache;
+}
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_add.c b/ldap/servers/slapd/back-ldbm/ldbm_add.c
index a22fce4..5854ebc 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_add.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_add.c
@@ -85,6 +85,7 @@ ldbm_back_add( Slapi_PBlock *pb )
struct backentry *addingentry = NULL;
struct backentry *parententry = NULL;
struct backentry *originalentry = NULL;
+ struct backentry *tmpentry = NULL;
ID pid;
int isroot;
char *errbuf= NULL;
@@ -104,8 +105,6 @@ ldbm_back_add( Slapi_PBlock *pb )
int ruv_c_init = 0;
int rc = 0;
int addingentry_id_assigned = 0;
- int addingentry_in_cache = 0;
- int tombstone_in_cache = 0;
Slapi_DN *sdn = NULL;
Slapi_DN parentsdn;
Slapi_Operation *operation;
@@ -222,34 +221,32 @@ ldbm_back_add( Slapi_PBlock *pb )
dblayer_txn_abort_ext(li, &txn, PR_FALSE);
noabort = 1;
slapi_pblock_set(pb, SLAPI_TXN, parent_txn);
-
- if (addingentry_in_cache) {
+ /* must duplicate addingentry before returning it to cache,
+ * which could free the entry. */
+ if ( (tmpentry = backentry_dup( addingentry )) == NULL ) {
+ ldap_result_code= LDAP_OPERATIONS_ERROR;
+ goto error_return;
+ }
+ if (cache_is_in_cache(&inst->inst_cache, addingentry)) {
/* addingentry is in cache. Remove it once. */
retval = CACHE_REMOVE(&inst->inst_cache, addingentry);
if (retval) {
LDAPDebug1Arg(LDAP_DEBUG_CACHE, "ldbm_add: cache_remove %s failed.\n",
slapi_entry_get_dn_const(addingentry->ep_entry));
}
- CACHE_RETURN(&inst->inst_cache, &addingentry);
- } else {
- backentry_free(&addingentry);
}
+ CACHE_RETURN(&inst->inst_cache, &addingentry);
slapi_pblock_set( pb, SLAPI_ADD_ENTRY, originalentry->ep_entry );
addingentry = originalentry;
- if ( (originalentry = backentry_dup( addingentry )) == NULL ) {
- ldap_result_code= LDAP_OPERATIONS_ERROR;
+ originalentry = tmpentry;
+ tmpentry = NULL;
+ /* Adding the resetted addingentry to the cache. */
+ if (cache_add_tentative(&inst->inst_cache, addingentry, NULL) < 0) {
+ LDAPDebug1Arg(LDAP_DEBUG_CACHE, "cache_add_tentative concurrency detected: %s\n",
+ slapi_entry_get_dn_const(addingentry->ep_entry));
+ ldap_result_code = LDAP_ALREADY_EXISTS;
goto error_return;
}
- if (addingentry_in_cache) {
- /* Adding the resetted addingentry to the cache. */
- if (cache_add_tentative(&inst->inst_cache, addingentry, NULL) != 0) {
- LDAPDebug1Arg(LDAP_DEBUG_CACHE, "cache_add_tentative concurrency detected: %s\n",
- slapi_entry_get_dn_const(addingentry->ep_entry));
- ldap_result_code = LDAP_ALREADY_EXISTS;
- addingentry_in_cache = 0;
- goto error_return;
- }
- }
if (ruv_c_init) {
/* reset the ruv txn stuff */
modify_term(&ruv_c, be);
@@ -531,7 +528,6 @@ ldbm_back_add( Slapi_PBlock *pb )
ldap_result_code= -1;
goto error_return; /* error result sent by find_entry2modify() */
}
- tombstone_in_cache = 1;
addingentry = backentry_dup( tombstoneentry );
if ( addingentry==NULL )
@@ -788,14 +784,13 @@ ldbm_back_add( Slapi_PBlock *pb )
/* Tentatively add the entry to the cache. We do this after adding any
* operational attributes to ensure that the cache is sized correctly. */
- if ( cache_add_tentative( &inst->inst_cache, addingentry, NULL )!= 0 )
+ if ( cache_add_tentative( &inst->inst_cache, addingentry, NULL ) < 0 )
{
LDAPDebug1Arg(LDAP_DEBUG_CACHE, "cache_add_tentative concurrency detected: %s\n",
slapi_entry_get_dn_const(addingentry->ep_entry));
ldap_result_code= LDAP_ALREADY_EXISTS;
goto error_return;
}
- addingentry_in_cache = 1;
/*
* Before we add the entry, find out if the syntax of the aci
@@ -830,7 +825,6 @@ ldbm_back_add( Slapi_PBlock *pb )
parent_found = 1;
parententry = NULL;
}
-
if ( (originalentry = backentry_dup(addingentry )) == NULL ) {
ldap_result_code= LDAP_OPERATIONS_ERROR;
goto error_return;
@@ -865,7 +859,7 @@ ldbm_back_add( Slapi_PBlock *pb )
goto error_return;
}
- retval = id2entry_add( be, addingentry, &txn );
+ retval = id2entry_add_ext(be, addingentry, &txn, 1, &myrc);
if (DB_LOCK_DEADLOCK == retval)
{
LDAPDebug( LDAP_DEBUG_ARGS, "add 1 DEADLOCK\n", 0, 0, 0 );
@@ -1085,10 +1079,6 @@ ldbm_back_add( Slapi_PBlock *pb )
retval = -1;
goto error_return;
}
- if (addingentry_in_cache) { /* decrease the refcnt added by tentative */
- CACHE_RETURN( &inst->inst_cache, &addingentry );
- }
- addingentry_in_cache = 1; /* reset it to make it sure... */
/*
* The tombstone was locked down in the cache... we can
* get rid of the entry in the cache now.
@@ -1103,9 +1093,6 @@ ldbm_back_add( Slapi_PBlock *pb )
CACHE_RETURN(&inst->inst_dncache, &bdn);
}
}
- cache_unlock_entry(&inst->inst_cache, tombstoneentry);
- CACHE_RETURN(&inst->inst_cache, &tombstoneentry);
- tombstone_in_cache = 0;
}
if (parent_found)
{
@@ -1173,21 +1160,18 @@ error_return:
}
if ( addingentry )
{
- if ( addingentry_in_cache )
- {
- if (inst) {
- CACHE_REMOVE(&inst->inst_cache, addingentry);
- /* tell frontend not to free this entry */
- slapi_pblock_set(pb, SLAPI_ADD_ENTRY, NULL);
- }
+ if (inst && cache_is_in_cache(&inst->inst_cache, addingentry)) {
+ CACHE_REMOVE(&inst->inst_cache, addingentry);
+ /* tell frontend not to free this entry */
+ slapi_pblock_set(pb, SLAPI_ADD_ENTRY, NULL);
}
- else
+ else if (!cache_has_otherref(&inst->inst_cache, addingentry))
{
if (!is_resurect_operation) { /* if resurect, tombstoneentry is dupped. */
backentry_clear_entry(addingentry); /* e is released in the frontend */
}
- backentry_free( &addingentry ); /* release the backend wrapper, here */
}
+ CACHE_RETURN( &inst->inst_cache, &addingentry );
}
if (rc == DB_RUNRECOVERY) {
dblayer_remember_disk_filled(li);
@@ -1240,12 +1224,6 @@ diskfull_return:
opreturn = -1;
slapi_pblock_set(pb, SLAPI_PLUGIN_OPRETURN, &opreturn);
}
- if (addingentry_in_cache && addingentry && inst) {
- CACHE_REMOVE(&inst->inst_cache, addingentry);
- /* tell frontend not to free this entry */
- slapi_pblock_set(pb, SLAPI_ADD_ENTRY, NULL);
- }
-
slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, &ldap_result_message);
}
@@ -1263,11 +1241,11 @@ diskfull_return:
common_return:
if (inst) {
- if(tombstone_in_cache && tombstoneentry) {
+ if (tombstoneentry && cache_is_in_cache(&inst->inst_cache, tombstoneentry)) {
cache_unlock_entry(&inst->inst_cache, tombstoneentry);
CACHE_RETURN(&inst->inst_cache, &tombstoneentry);
}
- if (addingentry_in_cache && addingentry) {
+ if (addingentry) {
if ((0 == retval) && entryrdn_get_switch()) { /* subtree-rename: on */
/* since adding the entry to the entry cache was successful,
* let's add the dn to dncache, if not yet done. */
@@ -1319,6 +1297,7 @@ common_return:
slapi_send_ldap_result( pb, ldap_result_code, ldap_result_matcheddn, ldap_result_message, 0, NULL );
}
backentry_free(&originalentry);
+ backentry_free(&tmpentry);
slapi_sdn_done(&parentsdn);
slapi_ch_free( (void**)&ldap_result_matcheddn );
slapi_ch_free( (void**)&errbuf );
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_delete.c b/ldap/servers/slapd/back-ldbm/ldbm_delete.c
index 97c21eb..ba2af26 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_delete.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_delete.c
@@ -61,6 +61,7 @@ ldbm_back_delete( Slapi_PBlock *pb )
struct backentry *e = NULL;
struct backentry *tombstone = NULL;
struct backentry *original_tombstone = NULL;
+ struct backentry *tmptombstone = NULL;
const char *dn = NULL;
back_txn txn;
back_txnid parent_txn;
@@ -88,8 +89,6 @@ ldbm_back_delete( Slapi_PBlock *pb )
int delete_tombstone_entry = 0; /* We must remove the given tombstone entry from the DB */
int create_tombstone_entry = 0; /* We perform a "regular" LDAP delete but since we use */
/* replication, we must create a new tombstone entry */
- int tombstone_in_cache = 0;
- int e_in_cache = 0;
int remove_e_from_cache = 0;
entry_address *addr;
int addordel_flags = 0; /* passed to index_addordel */
@@ -103,6 +102,9 @@ ldbm_back_delete( Slapi_PBlock *pb )
int myrc = 0;
PRUint64 conn_id;
int op_id;
+ ID ep_id = 0;
+ ID tomb_ep_id = 0;
+
if (slapi_pblock_get(pb, SLAPI_CONN_ID, &conn_id) < 0) {
conn_id = 0; /* connection is NULL */
}
@@ -205,7 +207,7 @@ ldbm_back_delete( Slapi_PBlock *pb )
*/
txn.back_txn_txn = NULL; /* ready to create the child transaction */
for (retry_count = 0; retry_count < RETRY_TIMES; retry_count++) {
- if (txn.back_txn_txn && (txn.back_txn_txn != parent_txn)) {
+ if (txn.back_txn_txn && (txn.back_txn_txn != parent_txn)) { /* retry_count > 0 */
Slapi_Entry *ent = NULL;
/* Don't release SERIAL LOCK */
@@ -226,25 +228,30 @@ ldbm_back_delete( Slapi_PBlock *pb )
/* reset tombstone entry */
if (original_tombstone) {
- if (tombstone_in_cache) {
- CACHE_REMOVE(&inst->inst_cache, tombstone);
- CACHE_RETURN(&inst->inst_cache, &tombstone);
- tombstone = NULL;
- tombstone_in_cache = 0;
- } else {
- backentry_free(&tombstone);
- }
- tombstone = original_tombstone;
- if ( (original_tombstone = backentry_dup( tombstone )) == NULL ) {
+ /* must duplicate tombstone before returning it to cache,
+ * which could free the entry. */
+ if ( (tmptombstone = backentry_dup( original_tombstone )) == NULL ) {
ldap_result_code= LDAP_OPERATIONS_ERROR;
goto error_return;
}
+ if (cache_is_in_cache(&inst->inst_cache, tombstone)) {
+ CACHE_REMOVE(&inst->inst_cache, tombstone);
+ }
+ CACHE_RETURN(&inst->inst_cache, &tombstone);
+ if (tombstone) {
+ slapi_log_error(SLAPI_LOG_FATAL, "ldbm_back_delete",
+ "conn=%lu op=%d [retry: %d] tombstone %s is not freed!!! refcnt %d, state %d\n",
+ conn_id, op_id, retry_count, slapi_entry_get_dn(tombstone->ep_entry),
+ tombstone->ep_refcnt, tombstone->ep_state);
+ }
+ tombstone = original_tombstone;
+ original_tombstone = tmptombstone;
+ tmptombstone = NULL;
+ } else {
+ slapi_log_error(SLAPI_LOG_FATAL, "ldbm_back_delete",
+ "conn=%lu op=%d [retry: %d] No original_tombstone for %s!!\n",
+ conn_id, op_id, retry_count, slapi_entry_get_dn(e->ep_entry));
}
- /* reset original entry in cache */
- if (!e_in_cache) {
- CACHE_ADD(&inst->inst_cache, e, NULL);
- e_in_cache = 1;
- }
if (ruv_c_init) {
/* reset the ruv txn stuff */
modify_term(&ruv_c, be);
@@ -252,8 +259,7 @@ ldbm_back_delete( Slapi_PBlock *pb )
}
/* We're re-trying */
- LDAPDebug0Args(LDAP_DEBUG_BACKLDBM,
- "Delete Retrying Transaction\n");
+ LDAPDebug0Args(LDAP_DEBUG_BACKLDBM, "Delete Retrying Transaction\n");
#ifndef LDBM_NO_BACKOFF_DELAY
{
PRIntervalTime interval;
@@ -295,12 +301,11 @@ ldbm_back_delete( Slapi_PBlock *pb )
LDAPDebug0Args(LDAP_DEBUG_BACKLDBM, "ldbm_back_delete: Deleting entry is already deleted.\n");
goto error_return; /* error result sent by find_entry2modify() */
}
- e_in_cache = 1; /* e is cached */
-
+ ep_id = e->ep_id;
retval = slapi_entry_has_children(e->ep_entry);
if (retval) {
ldap_result_code= LDAP_NOT_ALLOWED_ON_NONLEAF;
- slapi_log_error(SLAPI_LOG_FATAL, "ldbm_back_delete",
+ slapi_log_error(SLAPI_LOG_BACKLDBM, "ldbm_back_delete",
"conn=%lu op=%d Deleting entry %s has %d children.\n",
conn_id, op_id, slapi_entry_get_dn(e->ep_entry), retval);
retval = -1;
@@ -548,12 +553,11 @@ ldbm_back_delete( Slapi_PBlock *pb )
op |= PARENTUPDATE_DELETE_TOMBSTONE;
}
retval = parent_update_on_childchange(&parent_modify_c, op, &haschildren);
- slapi_log_error(SLAPI_LOG_BACKLDBM, "ldbm_back_delete",
- "conn=%lu op=%d parent_update_on_childchange: old_entry=0x%p, new_entry=0x%p, rc=%d\n",
- conn_id, op_id, parent_modify_c.old_entry, parent_modify_c.new_entry, retval);
-
/* The modify context now contains info needed later */
if (0 != retval) {
+ slapi_log_error(SLAPI_LOG_FATAL, "ldbm_back_delete",
+ "conn=%lu op=%d parent_update_on_childchange: old_entry=0x%p, new_entry=0x%p, rc=%d\n",
+ conn_id, op_id, parent_modify_c.old_entry, parent_modify_c.new_entry, retval);
ldap_result_code= LDAP_OPERATIONS_ERROR;
slapi_sdn_done(&parentsdn);
retval = -1;
@@ -610,6 +614,7 @@ ldbm_back_delete( Slapi_PBlock *pb )
parentuniqueid= slapi_entry_get_uniqueid(parent_modify_c.old_entry->ep_entry);
}
tombstone = backentry_dup( e );
+ tomb_ep_id = tombstone->ep_id;
slapi_entry_set_dn(tombstone->ep_entry,tombstone_dn); /* Consumes DN */
if (entryrdn_get_switch()) /* subtree-rename: on */
{
@@ -720,13 +725,10 @@ ldbm_back_delete( Slapi_PBlock *pb )
* entry is removed from the cache.
*/
retval = cache_add_tentative(&inst->inst_cache, tombstone, NULL);
- if (0 == retval) {
- tombstone_in_cache = 1;
- } else {
+ if (0 > retval) {
slapi_log_error(SLAPI_LOG_CACHE, "ldbm_back_delete",
"conn=%lu op=%d tombstone entry %s failed to add to the cache: %d\n",
conn_id, op_id, slapi_entry_get_dn(tombstone->ep_entry), retval);
- tombstone_in_cache = 0;
if (LDBM_OS_ERR_IS_DISKFULL(retval)) disk_full = 1;
DEL_SET_ERROR(ldap_result_code,
LDAP_OPERATIONS_ERROR, retry_count);
@@ -745,61 +747,6 @@ ldbm_back_delete( Slapi_PBlock *pb )
DEL_SET_ERROR(ldap_result_code, LDAP_OPERATIONS_ERROR, retry_count);
goto error_return;
}
- if (tombstone_in_cache) {
- retval = cache_replace(&inst->inst_cache, e, tombstone);
- if (retval) {
- LDAPDebug(LDAP_DEBUG_CACHE, "ldbm_back_delete: cache_replace failed (%d): %s --> %s\n",
- retval, slapi_entry_get_dn(e->ep_entry), slapi_entry_get_dn(tombstone->ep_entry));
- retval= -1;
- DEL_SET_ERROR(ldap_result_code, LDAP_OPERATIONS_ERROR, retry_count);
- goto error_return;
- } else {
- e_in_cache = 0;
- }
- } else {
- struct backentry *imposter = NULL;
- retval = CACHE_ADD(&inst->inst_cache, tombstone, &imposter);
- if (retval > 0) {
- if (imposter) {
- /*
- * The same tombstone entry (different Slapi_Entry) is already
- * generated and set to cache. Back off.
- */
- CACHE_RETURN(&inst->inst_cache, &imposter);
- LDAPDebug1Arg(LDAP_DEBUG_CACHE,
- "ldbm_delete: cache add: same DN tombstone in cache: %s\n",
- slapi_entry_get_dn(tombstone->ep_entry));
- } else {
- /*
- * The same tombstone entry (same Slapi_Entry) is being created.
- * Something is wrong. We should clean it up from the cache,
- * and back off.
- */
- tombstone_in_cache = 1;
- LDAPDebug1Arg(LDAP_DEBUG_CACHE,
- "ldbm_delete: cache add: same tombstone in cache: %s\n",
- slapi_entry_get_dn(tombstone->ep_entry));
- }
- retval= -1;
- DEL_SET_ERROR(ldap_result_code, LDAP_OPERATIONS_ERROR, retry_count);
- goto error_return;
- } else if (retval < 0) {
- LDAPDebug1Arg(LDAP_DEBUG_CACHE,
- "ldbm_delete: cache add: Add %s failed.\n",
- slapi_entry_get_dn(tombstone->ep_entry));
- /* Complete add error */
- retval= -1;
- DEL_SET_ERROR(ldap_result_code, LDAP_OPERATIONS_ERROR, retry_count);
- goto error_return;
- }
- }
- if (tombstone_in_cache) {
- /* tombstone was already added to the cache via cache_add_tentative (to reserve its spot in the cache)
- and/or id2entry_add - so it already had one refcount - cache_replace adds another refcount -
- drop the extra ref added by cache_replace */
- CACHE_RETURN( &inst->inst_cache, &tombstone );
- }
- tombstone_in_cache = 1;
}
else
{
@@ -1203,6 +1150,15 @@ ldbm_back_delete( Slapi_PBlock *pb )
retval = -1;
goto error_return;
}
+ if (create_tombstone_entry) {
+ retval = cache_replace(&inst->inst_cache, e, tombstone);
+ if (retval) {
+ LDAPDebug(LDAP_DEBUG_CACHE, "ldbm_back_delete: cache_replace failed (%d): %s --> %s\n",
+ retval, slapi_entry_get_dn(e->ep_entry), slapi_entry_get_dn(tombstone->ep_entry));
+ retval= -1;
+ goto error_return;
+ }
+ }
/* call the transaction post delete plugins just before the commit */
if (plugin_call_plugins(pb, SLAPI_PLUGIN_BE_TXN_POST_DELETE_FN)) {
@@ -1243,22 +1199,26 @@ ldbm_back_delete( Slapi_PBlock *pb )
/* delete from cache and clean up */
if (e) {
- if (entryrdn_get_switch()) { /* subtree-rename: on */
+ if (cache_is_in_cache(&inst->inst_cache, e)) {
+ ep_id = e->ep_id; /* Otherwise, e might have been freed. */
+ CACHE_REMOVE(&inst->inst_cache, e);
+ }
+ cache_unlock_entry(&inst->inst_cache, e);
+ CACHE_RETURN(&inst->inst_cache, &e);
+ /*
+ * e is unlocked and no longer in cache.
+ * It could be freed at any moment.
+ */
+ e = NULL;
+
+ if (entryrdn_get_switch() && ep_id) { /* subtree-rename: on */
/* since the op was successful, delete the tombstone dn from the dn cache */
- struct backdn *bdn = dncache_find_id(&inst->inst_dncache, e->ep_id);
+ struct backdn *bdn = dncache_find_id(&inst->inst_dncache, ep_id);
if (bdn) { /* in the dncache, remove it. */
CACHE_REMOVE(&inst->inst_dncache, bdn);
CACHE_RETURN(&inst->inst_dncache, &bdn);
}
}
- if (e_in_cache) {
- CACHE_REMOVE(&inst->inst_cache, e);
- cache_unlock_entry(&inst->inst_cache, e);
- CACHE_RETURN(&inst->inst_cache, &e);
- } else {
- cache_unlock_entry(&inst->inst_cache, e);
- }
- e = NULL;
}
if (ruv_c_init) {
@@ -1288,43 +1248,23 @@ ldbm_back_delete( Slapi_PBlock *pb )
error_return:
if (tombstone) {
- if (entryrdn_get_switch()) { /* subtree-rename: on */
+ if (cache_is_in_cache(&inst->inst_cache, tombstone)) {
+ tomb_ep_id = tombstone->ep_id; /* Otherwise, tombstone might have been freed. */
+ }
+ if (entryrdn_get_switch() && tomb_ep_id) { /* subtree-rename: on */
struct backdn *bdn = dncache_find_id(&inst->inst_dncache, tombstone->ep_id);
if (bdn) { /* already in the dncache. Delete it. */
CACHE_REMOVE(&inst->inst_dncache, bdn);
CACHE_RETURN(&inst->inst_dncache, &bdn);
}
}
-#ifdef CACHE_DEBUG
- check_entry_cache(&inst->inst_cache, tombstone, tombstone_in_cache);
-#endif
- if (tombstone_in_cache) { /* successfully replaced */
- CACHE_REMOVE( &inst->inst_cache, tombstone );
- CACHE_RETURN( &inst->inst_cache, &tombstone );
- tombstone = NULL;
- tombstone_in_cache = 0;
- } else {
- backentry_free( &tombstone );
- }
- }
- /* Need to return to cache after post op plugins are called */
- if (e) {
-#ifdef CACHE_DEBUG
- check_entry_cache(&inst->inst_cache, e, e_in_cache);
-#endif
- if (e_in_cache) {
- if (remove_e_from_cache) {
- /* The entry is already transformed to a tombstone. */
- CACHE_REMOVE( &inst->inst_cache, e );
- }
- cache_unlock_entry( &inst->inst_cache, e );
- CACHE_RETURN( &inst->inst_cache, &e );
- } else {
- cache_unlock_entry( &inst->inst_cache, e );
+ if (cache_is_in_cache(&inst->inst_cache, tombstone)) {
+ CACHE_REMOVE(&inst->inst_cache, tombstone);
}
+ CACHE_RETURN( &inst->inst_cache, &tombstone );
+ tombstone = NULL;
}
-
if (retval == DB_RUNRECOVERY) {
dblayer_remember_disk_filled(li);
ldbm_nasty("Delete",79,retval);
@@ -1414,16 +1354,8 @@ common_return:
}
}
}
-#ifdef CACHE_DEBUG
- check_entry_cache(&inst->inst_cache, tombstone, tombstone_in_cache);
-#endif
- if (tombstone_in_cache) { /* successfully replaced */
- CACHE_RETURN( &inst->inst_cache, &tombstone );
- tombstone = NULL;
- tombstone_in_cache = 0;
- } else {
- backentry_free( &tombstone );
- }
+ CACHE_RETURN( &inst->inst_cache, &tombstone );
+ tombstone = NULL;
}
/* result code could be used in the bepost plugin functions. */
@@ -1435,6 +1367,22 @@ common_return:
if (!delete_tombstone_entry) {
plugin_call_plugins (pb, SLAPI_PLUGIN_BE_POST_DELETE_FN);
}
+ /* Need to return to cache after post op plugins are called */
+ if (e) {
+ if (cache_is_in_cache(&inst->inst_cache, e)) {
+ if (remove_e_from_cache) {
+ /* The entry is already transformed to a tombstone. */
+ CACHE_REMOVE( &inst->inst_cache, e );
+ }
+ }
+ cache_unlock_entry( &inst->inst_cache, e );
+ CACHE_RETURN( &inst->inst_cache, &e );
+ /*
+ * e is unlocked and no longer in cache.
+ * It could be freed at any moment.
+ */
+ e = NULL;
+ }
if (inst && inst->inst_ref_count) {
slapi_counter_decrement(inst->inst_ref_count);
}
@@ -1453,7 +1401,8 @@ diskfull_return:
}
slapi_log_error(SLAPI_LOG_BACKLDBM, "ldbm_back_delete",
"conn=%lu op=%d modify_term: old_entry=0x%p, new_entry=0x%p, in_cache=%d\n",
- conn_id, op_id, parent_modify_c.old_entry, parent_modify_c.new_entry, parent_modify_c.new_entry_in_cache);
+ conn_id, op_id, parent_modify_c.old_entry, parent_modify_c.new_entry,
+ cache_is_in_cache(&inst->inst_cache, parent_modify_c.new_entry));
myrc = modify_term(&parent_modify_c, be);
if (rc == 0 && opcsn && !is_fixup_operation && !delete_tombstone_entry)
{
@@ -1471,6 +1420,7 @@ diskfull_return:
slapi_pblock_set(pb, SLAPI_DELETE_EXISTING_ENTRY, NULL);
}
backentry_free(&original_tombstone);
+ backentry_free(&tmptombstone);
slapi_ch_free((void**)&errbuf);
slapi_sdn_done(&nscpEntrySDN);
slapi_ch_free_string(&e_uniqueid);
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modify.c b/ldap/servers/slapd/back-ldbm/ldbm_modify.c
index 6f2da15..174a05e 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_modify.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_modify.c
@@ -65,7 +65,6 @@ void modify_init(modify_context *mc,struct backentry *old_entry)
PR_ASSERT(NULL == mc->new_entry);
mc->old_entry = old_entry;
- mc->new_entry_in_cache = 0;
mc->attr_encrypt = 1;
}
@@ -86,6 +85,9 @@ int modify_apply_mods_ignore_error(modify_context *mc, Slapi_Mods *smods, int er
ret = entry_apply_mods_ignore_error( mc->new_entry->ep_entry, slapi_mods_get_ldapmods_byref(smods), error);
}
mc->smods= smods;
+ if (error == ret) {
+ ret = LDAP_SUCCESS;
+ }
return ret;
}
@@ -96,16 +98,13 @@ int modify_term(modify_context *mc,struct backend *be)
slapi_mods_free(&mc->smods);
/* Unlock and return entries */
- if (NULL != mc->old_entry) {
+ if (mc->old_entry) {
cache_unlock_entry(&inst->inst_cache, mc->old_entry);
CACHE_RETURN( &(inst->inst_cache), &(mc->old_entry) );
mc->old_entry= NULL;
}
- if (mc->new_entry_in_cache) {
- CACHE_RETURN( &(inst->inst_cache), &(mc->new_entry) );
- } else {
- backentry_free(&(mc->new_entry));
- }
+
+ CACHE_RETURN(&(inst->inst_cache), &(mc->new_entry));
mc->new_entry= NULL;
return 0;
}
@@ -115,11 +114,9 @@ int modify_switch_entries(modify_context *mc,backend *be)
{
ldbm_instance *inst = (ldbm_instance *) be->be_instance_info;
int ret = 0;
- if (mc->old_entry!=NULL && mc->new_entry!=NULL) {
+ if (mc->old_entry && mc->new_entry) {
ret = cache_replace(&(inst->inst_cache), mc->old_entry, mc->new_entry);
- if (ret == 0) {
- mc->new_entry_in_cache = 1;
- } else {
+ if (ret) {
LDAPDebug(LDAP_DEBUG_CACHE, "modify_switch_entries: replacing %s with %s failed (%d)\n",
slapi_entry_get_dn(mc->old_entry->ep_entry),
slapi_entry_get_dn(mc->new_entry->ep_entry), ret);
@@ -140,13 +137,19 @@ modify_unswitch_entries(modify_context *mc,backend *be)
ldbm_instance *inst = (ldbm_instance *) be->be_instance_info;
int ret = 0;
- if (mc->old_entry && mc->new_entry && mc->new_entry_in_cache) {
+ if (mc->old_entry && mc->new_entry &&
+ cache_is_in_cache(&inst->inst_cache, mc->new_entry)) {
/* switch the entries, and reset the new, new, entry */
tmp_be = mc->new_entry;
mc->new_entry = mc->old_entry;
mc->new_entry->ep_state = 0;
- mc->new_entry->ep_refcnt = 0;
- mc->new_entry_in_cache = 0;
+ if (cache_has_otherref(&(inst->inst_cache), mc->new_entry)) {
+ /* some other thread refers the entry */
+ CACHE_RETURN(&(inst->inst_cache), &(mc->new_entry));
+ } else {
+ /* don't call CACHE_RETURN, that frees the entry! */
+ mc->new_entry->ep_refcnt = 0;
+ }
mc->old_entry = tmp_be;
ret = cache_replace(&(inst->inst_cache), mc->old_entry, mc->new_entry);
@@ -157,9 +160,7 @@ modify_unswitch_entries(modify_context *mc,backend *be)
* "old" one. modify_term() will then return the "new" entry.
*/
cache_unlock_entry(&inst->inst_cache, mc->new_entry);
- CACHE_RETURN( &(inst->inst_cache), &(mc->old_entry) );
- mc->new_entry_in_cache = 1;
- mc->old_entry = NULL;
+ cache_lock_entry(&inst->inst_cache, mc->old_entry);
} else {
LDAPDebug(LDAP_DEBUG_CACHE, "modify_unswitch_entries: replacing %s with %s failed (%d)\n",
slapi_entry_get_dn(mc->old_entry->ep_entry),
@@ -391,7 +392,8 @@ ldbm_back_modify( Slapi_PBlock *pb )
backend *be;
ldbm_instance *inst = NULL;
struct ldbminfo *li;
- struct backentry *e = NULL, *ec = NULL, *original_entry = NULL;
+ struct backentry *e = NULL, *ec = NULL;
+ struct backentry *original_entry = NULL, *tmpentry = NULL;
Slapi_Entry *postentry = NULL;
LDAPMod **mods = NULL;
LDAPMod **mods_original = NULL;
@@ -410,7 +412,6 @@ ldbm_back_modify( Slapi_PBlock *pb )
int rc = 0;
Slapi_Operation *operation;
entry_address *addr;
- int ec_in_cache = 0;
int is_fixup_operation= 0;
int is_ruv = 0; /* True if the current entry is RUV */
CSN *opcsn = NULL;
@@ -512,14 +513,22 @@ ldbm_back_modify( Slapi_PBlock *pb )
slapi_pblock_get(pb, SLAPI_MODIFY_MODS, &mods);
ldap_mods_free(mods, 1);
slapi_pblock_set(pb, SLAPI_MODIFY_MODS, copy_mods(mods_original));
- /* ec is not really added to the cache until cache_replace, so we
- don't have to worry about the cache here */
- backentry_free(&ec);
- slapi_pblock_set( pb, SLAPI_MODIFY_EXISTING_ENTRY, original_entry->ep_entry );
- ec = original_entry;
- if ( (original_entry = backentry_dup( ec )) == NULL ) {
- ldap_result_code= LDAP_OPERATIONS_ERROR;
- goto error_return;
+
+ /* reset ec set cache in id2entry_add_ext */
+ if (ec) {
+ /* must duplicate ec before returning it to cache,
+ * which could free the entry. */
+ if ( (tmpentry = backentry_dup( ec )) == NULL ) {
+ ldap_result_code= LDAP_OPERATIONS_ERROR;
+ goto error_return;
+ }
+ if (cache_is_in_cache(&inst->inst_cache, ec)) {
+ CACHE_REMOVE(&inst->inst_cache, ec);
+ }
+ CACHE_RETURN(&inst->inst_cache, &ec);
+ ec = original_entry;
+ original_entry = tmpentry;
+ tmpentry = NULL;
}
if (ruv_c_init) {
@@ -806,15 +815,12 @@ ldbm_back_modify( Slapi_PBlock *pb )
goto error_return;
}
/* e uncached */
- /* we must return both e (which has been deleted) and new entry ec */
- /* cache_replace removes e from the caches */
+ /* we must return both e (which has been deleted) and new entry ec to cache */
+ /* cache_replace removes e from the cache hash tables */
cache_unlock_entry( &inst->inst_cache, e );
CACHE_RETURN( &inst->inst_cache, &e );
-
/* lock new entry in cache to prevent usage until we are complete */
cache_lock_entry( &inst->inst_cache, ec );
- ec_in_cache = 1;
-
postentry = slapi_entry_dup( ec->ep_entry );
slapi_pblock_set( pb, SLAPI_ENTRY_POST_OP, postentry );
@@ -920,11 +926,11 @@ error_return:
}
/* if ec is in cache, remove it, then add back e if we still have it */
- if (inst && ec_in_cache) {
+ if (inst && cache_is_in_cache(&inst->inst_cache, ec)) {
CACHE_REMOVE( &inst->inst_cache, ec );
/* if ec was in cache, e was not - add back e */
if (e) {
- if (CACHE_ADD( &inst->inst_cache, e, NULL )) {
+ if (CACHE_ADD( &inst->inst_cache, e, NULL ) < 0) {
LDAPDebug1Arg(LDAP_DEBUG_CACHE, "ldbm_modify: CACHE_ADD %s failed\n",
slapi_entry_get_dn(e->ep_entry));
}
@@ -935,18 +941,15 @@ common_return:
slapi_mods_done(&smods);
if (inst) {
- if (ec_in_cache) {
- cache_unlock_entry( &inst->inst_cache, ec);
- CACHE_RETURN( &inst->inst_cache, &ec );
- } else {
- backentry_free(&ec);
+ if (cache_is_in_cache(&inst->inst_cache, ec)) {
+ cache_unlock_entry(&inst->inst_cache, ec);
+ } else if (e) {
/* if ec was not in cache, cache_replace was not done.
* i.e., e was not unlocked. */
- if (e) {
- cache_unlock_entry( &inst->inst_cache, e);
- CACHE_RETURN( &inst->inst_cache, &e);
- }
+ cache_unlock_entry(&inst->inst_cache, e);
+ CACHE_RETURN(&inst->inst_cache, &e);
}
+ CACHE_RETURN(&inst->inst_cache, &ec);
if (inst->inst_ref_count) {
slapi_counter_decrement(inst->inst_ref_count);
}
@@ -976,6 +979,7 @@ common_return:
/* free our backups */
ldap_mods_free(mods_original, 1);
backentry_free(&original_entry);
+ backentry_free(&tmpentry);
slapi_ch_free_string(&errbuf);
return rc;
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c b/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
index 8b86a14..fe68f38 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
@@ -50,7 +50,7 @@ static void moddn_unlock_and_return_entry(backend *be,struct backentry **targete
static int moddn_newrdn_mods(Slapi_PBlock *pb, const char *olddn, struct backentry *ec, Slapi_Mods *smods_wsi, int is_repl_op);
static IDList *moddn_get_children(back_txn *ptxn, Slapi_PBlock *pb, backend *be, struct backentry *parententry, Slapi_DN *parentdn, struct backentry ***child_entries, struct backdn ***child_dns, int is_resurect_operation);
static int moddn_rename_children(back_txn *ptxn, Slapi_PBlock *pb, backend *be, IDList *children, Slapi_DN *dn_parentdn, Slapi_DN *dn_newsuperiordn, struct backentry *child_entries[]);
-static int modrdn_rename_entry_update_indexes(back_txn *ptxn, Slapi_PBlock *pb, struct ldbminfo *li, struct backentry *e, struct backentry **ec, Slapi_Mods *smods1, Slapi_Mods *smods2, Slapi_Mods *smods3, int *e_in_cache, int *ec_in_cache);
+static int modrdn_rename_entry_update_indexes(back_txn *ptxn, Slapi_PBlock *pb, struct ldbminfo *li, struct backentry *e, struct backentry **ec, Slapi_Mods *smods1, Slapi_Mods *smods2, Slapi_Mods *smods3);
static void mods_remove_nsuniqueid(Slapi_Mods *smods);
#define MOD_SET_ERROR(rc, error, count) \
@@ -67,8 +67,6 @@ ldbm_back_modrdn( Slapi_PBlock *pb )
struct ldbminfo *li;
struct backentry *e= NULL;
struct backentry *ec= NULL;
- int ec_in_cache= 0;
- int e_in_cache= 0;
back_txn txn;
back_txnid parent_txn;
int retval = -1;
@@ -83,8 +81,7 @@ ldbm_back_modrdn( Slapi_PBlock *pb )
struct backentry *parententry= NULL;
struct backentry *newparententry= NULL;
struct backentry *original_entry = NULL;
- struct backentry *original_parent = NULL;
- struct backentry *original_newparent = NULL;
+ struct backentry *tmpentry = NULL;
modify_context parent_modify_context = {0};
modify_context newparent_modify_context = {0};
modify_context ruv_c = {0};
@@ -270,29 +267,22 @@ ldbm_back_modrdn( Slapi_PBlock *pb )
slapi_sdn_free(&dn_newsuperiordn);
slapi_pblock_set(pb, SLAPI_MODRDN_NEWSUPERIOR_SDN, orig_dn_newsuperiordn);
orig_dn_newsuperiordn = slapi_sdn_dup(orig_dn_newsuperiordn);
-#ifdef CACHE_DEBUG
- check_entry_cache(&inst->inst_cache, ec, ec_in_cache);
-#endif
- if (ec_in_cache) {
- /* New entry 'ec' is in the entry cache.
- * Remove it from the cache . */
+ /* must duplicate ec before returning it to cache,
+ * which could free the entry. */
+ if ( (tmpentry = backentry_dup( ec )) == NULL ) {
+ ldap_result_code= LDAP_OPERATIONS_ERROR;
+ goto error_return;
+ }
+ if (cache_is_in_cache(&inst->inst_cache, ec)) {
CACHE_REMOVE(&inst->inst_cache, ec);
- CACHE_RETURN(&inst->inst_cache, &ec);
-#ifdef DEBUG_CACHE
- PR_ASSERT(ec == NULL);
-#endif
- ec_in_cache = 0;
- } else {
- backentry_free(&ec);
}
- /* make sure the original entry is back in the cache if it was removed */
- if (!e_in_cache) {
- if (CACHE_ADD(&inst->inst_cache, e, NULL)) {
+ CACHE_RETURN(&inst->inst_cache, &ec);
+ if (!cache_is_in_cache(&inst->inst_cache, e)) {
+ if (CACHE_ADD(&inst->inst_cache, e, NULL) < 0) {
LDAPDebug1Arg(LDAP_DEBUG_CACHE,
"ldbm_back_modrdn: CACHE_ADD %s to cache failed\n",
slapi_entry_get_dn_const(e->ep_entry));
}
- e_in_cache = 1;
}
slapi_pblock_get( pb, SLAPI_MODRDN_EXISTING_ENTRY, &ent );
if (ent && (ent != original_entry->ep_entry)) {
@@ -300,16 +290,13 @@ ldbm_back_modrdn( Slapi_PBlock *pb )
slapi_pblock_set( pb, SLAPI_MODRDN_EXISTING_ENTRY, NULL );
}
ec = original_entry;
- if ( (original_entry = backentry_dup( ec )) == NULL ) {
- ldap_result_code= LDAP_OPERATIONS_ERROR;
- goto error_return;
- }
+ original_entry = tmpentry;
+ tmpentry = NULL;
slapi_pblock_set( pb, SLAPI_MODRDN_EXISTING_ENTRY, original_entry->ep_entry );
free_modrdn_existing_entry = 0; /* owned by original_entry now */
- if (!ec_in_cache) {
+ if (!cache_is_in_cache(&inst->inst_cache, ec)) {
/* Put the resetted entry 'ec' into the cache again. */
- if (cache_add_tentative( &inst->inst_cache, ec, NULL ) != 0) {
- ec_in_cache = 0; /* not in cache */
+ if (cache_add_tentative( &inst->inst_cache, ec, NULL ) < 0) {
/* allow modrdn even if the src dn and dest dn are identical */
if ( 0 != slapi_sdn_compare((const Slapi_DN *)&dn_newdn,
(const Slapi_DN *)sdn) ) {
@@ -321,8 +308,6 @@ ldbm_back_modrdn( Slapi_PBlock *pb )
}
/* so if the old dn is the same as the new dn, the entry will not be cached
until it is replaced with cache_replace */
- } else {
- ec_in_cache = 1;
}
}
@@ -509,7 +494,6 @@ ldbm_back_modrdn( Slapi_PBlock *pb )
ldap_result_code= -1;
goto error_return; /* error result sent by find_entry2modify() */
}
- e_in_cache = 1; /* e is in the cache and locked */
if (slapi_entry_flag_is_set(e->ep_entry, SLAPI_ENTRY_FLAG_TOMBSTONE) &&
!is_resurect_operation) {
ldap_result_code = LDAP_UNWILLING_TO_PERFORM;
@@ -747,8 +731,7 @@ ldbm_back_modrdn( Slapi_PBlock *pb )
}
/* create it in the cache - prevents others from creating it */
- if (( cache_add_tentative( &inst->inst_cache, ec, NULL ) != 0 ) ) {
- ec_in_cache = 0; /* not in cache */
+ if (( cache_add_tentative( &inst->inst_cache, ec, NULL ) < 0 ) ) {
/* allow modrdn even if the src dn and dest dn are identical */
if ( 0 != slapi_sdn_compare((const Slapi_DN *)&dn_newdn,
(const Slapi_DN *)sdn) ) {
@@ -764,46 +747,41 @@ ldbm_back_modrdn( Slapi_PBlock *pb )
}
/* so if the old dn is the same as the new dn, the entry will not be cached
until it is replaced with cache_replace */
- } else {
- ec_in_cache = 1;
}
-
/* Build the list of modifications required to the existing entry */
+ slapi_mods_init(&smods_generated,4);
+ slapi_mods_init(&smods_generated_wsi,4);
+ ldap_result_code = moddn_newrdn_mods(pb, slapi_sdn_get_ndn(sdn),
+ ec, &smods_generated_wsi, is_replicated_operation);
+ if (ldap_result_code != LDAP_SUCCESS) {
+ if (ldap_result_code == LDAP_UNWILLING_TO_PERFORM)
+ ldap_result_message = "Modification of old rdn attribute type not allowed.";
+ goto error_return;
+ }
+ if (!entryrdn_get_switch()) /* subtree-rename: off */
{
- slapi_mods_init(&smods_generated,4);
- slapi_mods_init(&smods_generated_wsi,4);
- ldap_result_code = moddn_newrdn_mods(pb, slapi_sdn_get_ndn(sdn),
- ec, &smods_generated_wsi, is_replicated_operation);
- if (ldap_result_code != LDAP_SUCCESS) {
- if (ldap_result_code == LDAP_UNWILLING_TO_PERFORM)
- ldap_result_message = "Modification of old rdn attribute type not allowed.";
- goto error_return;
- }
- if (!entryrdn_get_switch()) /* subtree-rename: off */
- {
- /*
- * Remove the old entrydn index entry, and add the new one.
- */
- slapi_mods_add( &smods_generated, LDAP_MOD_DELETE, LDBM_ENTRYDN_STR,
- strlen(backentry_get_ndn(e)), backentry_get_ndn(e));
- slapi_mods_add( &smods_generated, LDAP_MOD_REPLACE, LDBM_ENTRYDN_STR,
- strlen(backentry_get_ndn(ec)), backentry_get_ndn(ec));
- }
-
/*
- * Update parentid if we have a new superior.
- */
- if(slapi_sdn_get_dn(dn_newsuperiordn)!=NULL) {
- char buf[40]; /* Enough for an ID */
-
- if (parententry != NULL) {
- sprintf( buf, "%lu", (u_long)parententry->ep_id );
- slapi_mods_add_string(&smods_generated, LDAP_MOD_DELETE, LDBM_PARENTID_STR, buf);
- }
- if (newparententry != NULL) {
- sprintf( buf, "%lu", (u_long)newparententry->ep_id );
- slapi_mods_add_string(&smods_generated, LDAP_MOD_REPLACE, LDBM_PARENTID_STR, buf);
- }
+ * Remove the old entrydn index entry, and add the new one.
+ */
+ slapi_mods_add( &smods_generated, LDAP_MOD_DELETE, LDBM_ENTRYDN_STR,
+ strlen(backentry_get_ndn(e)), backentry_get_ndn(e));
+ slapi_mods_add( &smods_generated, LDAP_MOD_REPLACE, LDBM_ENTRYDN_STR,
+ strlen(backentry_get_ndn(ec)), backentry_get_ndn(ec));
+ }
+
+ /*
+ * Update parentid if we have a new superior.
+ */
+ if(slapi_sdn_get_dn(dn_newsuperiordn)!=NULL) {
+ char buf[40]; /* Enough for an ID */
+
+ if (parententry != NULL) {
+ sprintf( buf, "%lu", (u_long)parententry->ep_id );
+ slapi_mods_add_string(&smods_generated, LDAP_MOD_DELETE, LDBM_PARENTID_STR, buf);
+ }
+ if (newparententry != NULL) {
+ sprintf( buf, "%lu", (u_long)newparententry->ep_id );
+ slapi_mods_add_string(&smods_generated, LDAP_MOD_REPLACE, LDBM_PARENTID_STR, buf);
}
}
@@ -1029,7 +1007,7 @@ ldbm_back_modrdn( Slapi_PBlock *pb )
/*
* Update the indexes for the entry.
*/
- retval = modrdn_rename_entry_update_indexes(&txn, pb, li, e, &ec, &smods_generated, &smods_generated_wsi, &smods_operation_wsi, &e_in_cache, &ec_in_cache);
+ retval = modrdn_rename_entry_update_indexes(&txn, pb, li, e, &ec, &smods_generated, &smods_generated_wsi, &smods_operation_wsi);
if (DB_LOCK_DEADLOCK == retval)
{
/* Retry txn */
@@ -1472,19 +1450,13 @@ common_return:
}
/* remove the new entry from the cache if the op failed -
otherwise, leave it in */
-#ifdef CACHE_DEBUG
- check_entry_cache(&inst->inst_cache, ec, ec_in_cache);
-#endif
- if (ec_in_cache && ec && inst) {
- if (retval) {
+ if (ec && inst) {
+ if (retval && cache_is_in_cache(&inst->inst_cache, ec)) {
CACHE_REMOVE( &inst->inst_cache, ec );
}
CACHE_RETURN( &inst->inst_cache, &ec );
- } else {
- backentry_free( &ec );
}
ec = NULL;
- ec_in_cache = 0;
}
if (inst) {
@@ -1546,8 +1518,7 @@ common_return:
slapi_ch_free_string(&original_newrdn);
slapi_sdn_free(&orig_dn_newsuperiordn);
backentry_free(&original_entry);
- backentry_free(&original_parent);
- backentry_free(&original_newparent);
+ backentry_free(&tmpentry);
slapi_entry_free(original_targetentry);
slapi_ch_free((void**)&errbuf);
if (retval == 0 && opcsn != NULL && !is_fixup_operation)
@@ -1817,7 +1788,9 @@ mods_remove_nsuniqueid(Slapi_Mods *smods)
* mods contains the list of attribute change made.
*/
static int
-modrdn_rename_entry_update_indexes(back_txn *ptxn, Slapi_PBlock *pb, struct ldbminfo *li, struct backentry *e, struct backentry **ec, Slapi_Mods *smods1, Slapi_Mods *smods2, Slapi_Mods *smods3, int *e_in_cache, int *ec_in_cache)
+modrdn_rename_entry_update_indexes(back_txn *ptxn, Slapi_PBlock *pb, struct ldbminfo *li,
+ struct backentry *e, struct backentry **ec,
+ Slapi_Mods *smods1, Slapi_Mods *smods2, Slapi_Mods *smods3)
{
backend *be;
ldbm_instance *inst;
@@ -1825,7 +1798,6 @@ modrdn_rename_entry_update_indexes(back_txn *ptxn, Slapi_PBlock *pb, struct ldbm
char *msg;
Slapi_Operation *operation;
int is_ruv = 0; /* True if the current entry is RUV */
- int orig_ec_in_cache = 0;
int cache_rc = 0;
slapi_pblock_get( pb, SLAPI_BACKEND, &be );
@@ -1833,7 +1805,6 @@ modrdn_rename_entry_update_indexes(back_txn *ptxn, Slapi_PBlock *pb, struct ldbm
is_ruv = operation_is_flag_set(operation, OP_FLAG_REPL_RUV);
inst = (ldbm_instance *) be->be_instance_info;
- orig_ec_in_cache = *ec_in_cache;
/*
* Update the ID to Entry index.
* Note that id2entry_add replaces the entry, so the Entry ID stays the same.
@@ -1855,7 +1826,6 @@ modrdn_rename_entry_update_indexes(back_txn *ptxn, Slapi_PBlock *pb, struct ldbm
LDAPDebug( LDAP_DEBUG_ANY, "modrdn_rename_entry_update_indexes: id2entry_add failed, err=%d %s\n", retval, (msg = dblayer_strerror( retval )) ? msg : "", 0 );
goto error_return;
}
- *ec_in_cache = 1; /* id2entry_add adds to cache if not already in */
if(smods1!=NULL && slapi_mods_get_num_mods(smods1)>0)
{
/*
@@ -1943,13 +1913,6 @@ modrdn_rename_entry_update_indexes(back_txn *ptxn, Slapi_PBlock *pb, struct ldbm
retval= -1;
goto error_return;
}
- *e_in_cache = 0;
- if (orig_ec_in_cache) {
- /* ec was already added to the cache via cache_add_tentative (to reserve its spot in the cache)
- and/or id2entry_add - so it already had one refcount - cache_replace adds another refcount -
- drop the extra ref added by cache_replace */
- CACHE_RETURN( &inst->inst_cache, ec );
- }
error_return:
return retval;
}
@@ -1984,9 +1947,6 @@ moddn_rename_child_entry(
int olddncomps= 0;
int need= 1; /* For the '\0' */
int i;
- int e_in_cache = 1;
- int ec_in_cache = 0;
-
olddn = slapi_entry_get_dn((*ec)->ep_entry);
if (NULL == olddn) {
return retval;
@@ -2048,8 +2008,7 @@ moddn_rename_child_entry(
* Update all the indexes.
*/
retval = modrdn_rename_entry_update_indexes(ptxn, pb, li, e, ec,
- smodsp, NULL, NULL,
- &e_in_cache, &ec_in_cache);
+ smodsp, NULL, NULL);
/* JCMREPL - Should the children get updated modifiersname and lastmodifiedtime? */
slapi_mods_done(&smods);
}
diff --git a/ldap/servers/slapd/back-ldbm/parents.c b/ldap/servers/slapd/back-ldbm/parents.c
index d375519..f55d527 100644
--- a/ldap/servers/slapd/back-ldbm/parents.c
+++ b/ldap/servers/slapd/back-ldbm/parents.c
@@ -126,11 +126,11 @@ parent_update_on_childchange(modify_context *mc,int op, size_t *new_sub_count )
mod_op = LDAP_MOD_ADD;
} else if (PARENTUPDATE_DEL == op) {
if (!already_present) {
- /* This means that something is wrong---deleting a child but no subcount present on parent */
+ /* This means that there was a conflict. Before coming to this point,
+ * the entry to be deleted was deleted... */
LDAPDebug(LDAP_DEBUG_ANY, "Parent %s has no children. (op 0x%x, repl_op 0x%x)\n",
slapi_entry_get_dn(mc->old_entry->ep_entry), op, repl_op);
slapi_mods_free(&smods);
- PR_ASSERT(0);
return -1;
} else {
if (current_sub_count == 1) {
diff --git a/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h b/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h
index 240ece6..db1d320 100644
--- a/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h
+++ b/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h
@@ -87,8 +87,11 @@ int cache_add_tentative(struct cache *cache, struct backentry *e,
int cache_lock_entry(struct cache *cache, struct backentry *e);
void cache_unlock_entry(struct cache *cache, struct backentry *e);
int cache_replace(struct cache *cache, void *oldptr, void *newptr);
+int cache_has_otherref(struct cache *cache, void *bep);
+int cache_is_in_cache(struct cache *cache, void *ptr);
+
#ifdef CACHE_DEBUG
-void check_entry_cache(struct cache *cache, struct backentry *e, int in_cache);
+void check_entry_cache(struct cache *cache, struct backentry *e);
#endif
Hashtable *new_hash(u_long size, u_long offset, HashFn hfn,
9 years, 8 months
ldap/servers
by Noriko Hosoi
ldap/servers/plugins/replication/cl5_api.c | 31 ++-
ldap/servers/slapd/back-ldbm/back-ldbm.h | 2
ldap/servers/slapd/back-ldbm/cache.c | 237 ++++++++++++++-----------
ldap/servers/slapd/back-ldbm/ldbm_add.c | 75 ++-----
ldap/servers/slapd/back-ldbm/ldbm_delete.c | 219 ++++++++---------------
ldap/servers/slapd/back-ldbm/ldbm_modify.c | 90 ++++-----
ldap/servers/slapd/back-ldbm/ldbm_modrdn.c | 153 +++++-----------
ldap/servers/slapd/back-ldbm/parents.c | 4
ldap/servers/slapd/back-ldbm/proto-back-ldbm.h | 5
9 files changed, 383 insertions(+), 433 deletions(-)
New commits:
commit 6333936da2c4287e96b36fecc24a4c62da5a8ea2
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Tue Aug 19 14:42:52 2014 -0700
Ticket #47834 - Tombstone_to_glue: if parents are also converted to glue, the target entry's DN must be adjusted.
Bug Description: Test case to verify the problem crashed the server.
Fix Description:
1. Clean up entry cache related code
1-1. Changing cache log reentrant to avoid self deadlock.
1-2. Introducing cache_is_in_cache to get rid of local variables in
ldap_back_{add,delete,modify,modrdn}.
2. ldap_back_{add,delete,modify,modrdn}
2-1. As described in 1-2, removed [a-z]*_in_cache local variables.
2-2. In the deadlock retry loop, entries were duplicated by backentry_
dup after CACHE_REMOVE'd and CACHE_RETURN'ed. At the moment, the
entry could be already freed. Changed to create a duplicated
entry before calling CACHE_REMOVE and CACHE_RETURN.
3. _cl5NewDBFile (replication/cl5_api.c): When a leftover semaphore is
found, _cl5NewDBFile removes it and creates it, but it rarely fails
to delete and it causes the server restart fail. Adding a message
to remove such a leftover semaphore by ipcrm.
https://fedorahosted.org/389/ticket/47834
Reviewed by mreynolds(a)redhat.com (Thank you, Mark!!)
diff --git a/ldap/servers/plugins/replication/cl5_api.c b/ldap/servers/plugins/replication/cl5_api.c
index 85727f9..42e52ae 100644
--- a/ldap/servers/plugins/replication/cl5_api.c
+++ b/ldap/servers/plugins/replication/cl5_api.c
@@ -5784,7 +5784,7 @@ static int _cl5DBOpenFileByReplicaName (const char *replName, const char *replGe
if (checkDups)
{
PR_Lock (s_cl5Desc.fileLock);
- file_name = _cl5MakeFileName (replName, replGen);
+ file_name = _cl5MakeFileName (replName, replGen);
tmpObj = objset_find (s_cl5Desc.dbFiles, _cl5CompareDBFile, file_name);
slapi_ch_free((void **)&file_name);
if (tmpObj) /* this file already exist */
@@ -5859,10 +5859,10 @@ done:;
if (checkDups)
{
- PR_Unlock (s_cl5Desc.fileLock);
- }
+ PR_Unlock (s_cl5Desc.fileLock);
+ }
- return rc;
+ return rc;
}
/* adds file to the db file list */
@@ -6026,7 +6026,14 @@ out:
* and re-create it.
*/
if (PR_GetError() == PR_FILE_EXISTS_ERROR) {
+ PRErrorCode prerr;
PR_DeleteSemaphore((*dbFile)->semaName);
+ prerr = PR_GetError();
+ if (PR_SUCCESS != prerr) {
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl,
+ "_cl5NewDBFile: PR_DeleteSemaphore: %s; NSPR error - %d\n",
+ (*dbFile)->semaName ? (*dbFile)->semaName : "(nil)", prerr);
+ }
(*dbFile)->sema = PR_OpenSemaphore((*dbFile)->semaName,
PR_SEM_CREATE | PR_SEM_EXCL, 0666,
s_cl5Desc.dbConfig.maxConcurrentWrites );
@@ -6036,9 +6043,19 @@ out:
* we should just error out. */
if ((*dbFile)->sema == NULL )
{
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl,
- "_cl5NewDBFile: failed to create semaphore %s; NSPR error - %d\n",
- (*dbFile)->semaName ? (*dbFile)->semaName : "(nil)", PR_GetError());
+ PRErrorCode prerr = PR_GetError();
+ if (PR_FILE_EXISTS_ERROR == prerr) {
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl,
+ "_cl5NewDBFile: PR_OpenSemaphore: %s; sema: 0x%p, NSPR error - %d\n",
+ (*dbFile)->semaName ? (*dbFile)->semaName : "(nil)", (*dbFile)->sema, prerr);
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl,
+ " : Leftover semaphores may exist. "
+ "Run \"ipcs -s\", and remove them with \"ipcrm -s <SEMID>\" if any\n");
+ } else {
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl,
+ "_cl5NewDBFile: failed to create semaphore %s; NSPR error - %d\n",
+ (*dbFile)->semaName ? (*dbFile)->semaName : "(nil)", prerr);
+ }
rc = CL5_SYSTEM_ERROR;
goto done;
}
diff --git a/ldap/servers/slapd/back-ldbm/back-ldbm.h b/ldap/servers/slapd/back-ldbm/back-ldbm.h
index bd84e0f..938d261 100644
--- a/ldap/servers/slapd/back-ldbm/back-ldbm.h
+++ b/ldap/servers/slapd/back-ldbm/back-ldbm.h
@@ -403,7 +403,7 @@ struct cache {
Slapi_Counter *c_tries;
struct backcommon *c_lruhead; /* add entries here */
struct backcommon *c_lrutail; /* remove entries here */
- PRLock *c_mutex; /* lock for cache operations */
+ PRMonitor *c_mutex; /* lock for cache operations */
PRLock *c_emutexalloc_mutex;
};
diff --git a/ldap/servers/slapd/back-ldbm/cache.c b/ldap/servers/slapd/back-ldbm/cache.c
index 0732415..a98cf0c 100644
--- a/ldap/servers/slapd/back-ldbm/cache.c
+++ b/ldap/servers/slapd/back-ldbm/cache.c
@@ -544,10 +544,9 @@ int cache_init(struct cache *cache, size_t maxsize, long maxentries, int type)
cache->c_lruhead = cache->c_lrutail = NULL;
cache_make_hashes(cache, type);
- if (((cache->c_mutex = PR_NewLock()) == NULL) ||
- ((cache->c_emutexalloc_mutex = PR_NewLock()) == NULL)) {
- LDAPDebug(LDAP_DEBUG_ANY, "ldbm: cache_init: PR_NewLock failed\n",
- 0, 0, 0);
+ if (((cache->c_mutex = PR_NewMonitor()) == NULL) ||
+ ((cache->c_emutexalloc_mutex = PR_NewLock()) == NULL)) {
+ LDAPDebug0Args(LDAP_DEBUG_ANY, "ldbm: cache_init: PR_NewMonitor failed\n");
return 0;
}
LDAPDebug(LDAP_DEBUG_TRACE, "<= cache_init\n", 0, 0, 0);
@@ -634,13 +633,13 @@ static void entrycache_clear_int(struct cache *cache)
void cache_clear(struct cache *cache, int type)
{
- PR_Lock(cache->c_mutex);
+ cache_lock(cache);
if (CACHE_TYPE_ENTRY == type) {
entrycache_clear_int(cache);
} else if (CACHE_TYPE_DN == type) {
dncache_clear_int(cache);
}
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
}
static void erase_cache(struct cache *cache, int type)
@@ -664,7 +663,7 @@ void cache_destroy_please(struct cache *cache, int type)
slapi_counter_destroy(&cache->c_cursize);
slapi_counter_destroy(&cache->c_hits);
slapi_counter_destroy(&cache->c_tries);
- PR_DestroyLock(cache->c_mutex);
+ PR_DestroyMonitor(cache->c_mutex);
PR_DestroyLock(cache->c_emutexalloc_mutex);
}
@@ -688,7 +687,7 @@ static void entrycache_set_max_size(struct cache *cache, size_t bytes)
"WARNING -- Minimum cache size is %lu -- rounding up\n",
MINCACHESIZE, 0, 0);
}
- PR_Lock(cache->c_mutex);
+ cache_lock(cache);
cache->c_maxsize = bytes;
LOG("entry cache size set to %lu\n", bytes, 0, 0);
/* check for full cache, and clear out if necessary */
@@ -707,7 +706,7 @@ static void entrycache_set_max_size(struct cache *cache, size_t bytes)
erase_cache(cache, CACHE_TYPE_ENTRY);
cache_make_hashes(cache, CACHE_TYPE_ENTRY);
}
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
if (! dblayer_is_cachesize_sane(&bytes)) {
LDAPDebug(LDAP_DEBUG_ANY,
"WARNING -- Possible CONFIGURATION ERROR -- cachesize "
@@ -725,7 +724,7 @@ void cache_set_max_entries(struct cache *cache, long entries)
* was given in # entries instead of memory footprint. hopefully,
* we can eventually drop this.
*/
- PR_Lock(cache->c_mutex);
+ cache_lock(cache);
cache->c_maxentries = entries;
if (entries >= 0) {
LOG("entry cache entry-limit set to %lu\n", entries, 0, 0);
@@ -736,7 +735,7 @@ void cache_set_max_entries(struct cache *cache, long entries)
/* check for full cache, and clear out if necessary */
if (CACHE_FULL(cache))
eflush = entrycache_flush(cache);
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
while (eflush)
{
eflushtemp = BACK_LRU_NEXT(eflush, struct backentry *);
@@ -749,9 +748,9 @@ size_t cache_get_max_size(struct cache *cache)
{
size_t n = 0;
- PR_Lock(cache->c_mutex);
+ cache_lock(cache);
n = cache->c_maxsize;
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
return n;
}
@@ -759,9 +758,9 @@ long cache_get_max_entries(struct cache *cache)
{
long n;
- PR_Lock(cache->c_mutex);
+ cache_lock(cache);
n = cache->c_maxentries;
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
return n;
}
@@ -787,14 +786,14 @@ void cache_get_stats(struct cache *cache, PRUint64 *hits, PRUint64 *tries,
long *nentries, long *maxentries,
size_t *size, size_t *maxsize)
{
- PR_Lock(cache->c_mutex);
+ cache_lock(cache);
if (hits) *hits = slapi_counter_get_value(cache->c_hits);
if (tries) *tries = slapi_counter_get_value(cache->c_tries);
if (nentries) *nentries = cache->c_curentries;
if (maxentries) *maxentries = cache->c_maxentries;
if (size) *size = slapi_counter_get_value(cache->c_cursize);
if (maxsize) *maxsize = cache->c_maxsize;
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
}
void cache_debug_hash(struct cache *cache, char **out)
@@ -805,7 +804,7 @@ void cache_debug_hash(struct cache *cache, char **out)
Hashtable *ht = NULL;
char *name = "unknown";
- PR_Lock(cache->c_mutex);
+ cache_lock(cache);
*out = (char *)slapi_ch_malloc(1024);
**out = 0;
@@ -841,7 +840,7 @@ void cache_debug_hash(struct cache *cache, char **out)
sprintf(*out + strlen(*out), "%d[%d] ", j, slot_stats[j]);
slapi_ch_free((void **)&slot_stats);
}
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
}
@@ -947,14 +946,14 @@ int cache_remove(struct cache *cache, void *ptr)
}
e = (struct backcommon *)ptr;
- PR_Lock(cache->c_mutex);
+ cache_lock(cache);
if (CACHE_TYPE_ENTRY == e->ep_type) {
ASSERT(e->ep_refcnt > 0);
ret = entrycache_remove_int(cache, (struct backentry *)e);
} else if (CACHE_TYPE_DN == e->ep_type) {
ret = dncache_remove_int(cache, (struct backdn *)e);
}
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
return ret;
}
@@ -1014,7 +1013,7 @@ static int entrycache_replace(struct cache *cache, struct backentry *olde,
#endif
newndn = slapi_sdn_get_ndn(backentry_get_sdn(newe));
entry_size = cache_entry_size(newe);
- PR_Lock(cache->c_mutex);
+ cache_lock(cache);
/*
* First, remove the old entry from all the hashtables.
@@ -1034,7 +1033,7 @@ static int entrycache_replace(struct cache *cache, struct backentry *olde,
}
/* If fails, we have to make sure the both entires are removed from the cache,
* otherwise, we have no idea what's left in the cache or not... */
- if (!entry_same_dn(newe, (void *)oldndn) && (newe->ep_state & ENTRY_STATE_NOTINCACHE) == 0) {
+ if (cache_is_in_cache(cache, newe)) {
/* if we're doing a modrdn or turning an entry to a tombstone,
* the new entry can be in the dn table already, so we need to remove that too.
*/
@@ -1042,6 +1041,7 @@ static int entrycache_replace(struct cache *cache, struct backentry *olde,
{
slapi_counter_subtract(cache->c_cursize, newe->ep_size);
cache->c_curentries--;
+ newe->ep_refcnt--;
LOG("entry cache replace remove entry size %lu\n", newe->ep_size, 0, 0);
}
}
@@ -1064,7 +1064,7 @@ static int entrycache_replace(struct cache *cache, struct backentry *olde,
LOG("entry cache replace (%s): cache index tables out of sync - found dn [%d] id [%d]\n",
oldndn, found_in_dn, found_in_id);
#endif
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
return 1;
}
}
@@ -1073,32 +1073,32 @@ static int entrycache_replace(struct cache *cache, struct backentry *olde,
* tested enough that we believe it works.)
*/
if (!add_hash(cache->c_dntable, (void *)newndn, strlen(newndn), newe, (void **)&alte)) {
- LOG("entry cache replace (%s): can't add to dn table (returned %s)\n",
- newndn, alte?slapi_entry_get_dn(alte->ep_entry):"none", 0);
- PR_Unlock(cache->c_mutex);
- return 1;
+ LOG("entry cache replace (%s): can't add to dn table (returned %s)\n",
+ newndn, alte?slapi_entry_get_dn(alte->ep_entry):"none", 0);
+ cache_lock(cache);
+ return 1;
}
if (!add_hash(cache->c_idtable, &(newe->ep_id), sizeof(ID), newe, (void **)&alte)) {
- LOG("entry cache replace (%s): can't add to id table (returned %s)\n",
- newndn, alte?slapi_entry_get_dn(alte->ep_entry):"none", 0);
- if(remove_hash(cache->c_dntable, (void *)newndn, strlen(newndn)) == 0){
- LOG("entry cache replace: failed to remove dn table\n", 0, 0, 0);
- }
- PR_Unlock(cache->c_mutex);
- return 1;
+ LOG("entry cache replace (%s): can't add to id table (returned %s)\n",
+ newndn, alte?slapi_entry_get_dn(alte->ep_entry):"none", 0);
+ if(remove_hash(cache->c_dntable, (void *)newndn, strlen(newndn)) == 0){
+ LOG("entry cache replace: failed to remove dn table\n", 0, 0, 0);
+ }
+ cache_unlock(cache);
+ return 1;
}
#ifdef UUIDCACHE_ON
if (newuuid && !add_hash(cache->c_uuidtable, (void *)newuuid, strlen(newuuid),
newe, NULL)) {
- LOG("entry cache replace: can't add uuid\n", 0, 0, 0);
- if(remove_hash(cache->c_dntable, (void *)newndn, strlen(newndn)) == 0){
- LOG("entry cache replace: failed to remove dn table(uuid cache)\n", 0, 0, 0);
- }
- if(remove_hash(cache->c_idtable, &(newe->ep_id), sizeof(ID)) == 0){
- LOG("entry cache replace: failed to remove id table(uuid cache)\n", 0, 0, 0);
- }
- PR_Unlock(cache->c_mutex);
- return 1;
+ LOG("entry cache replace: can't add uuid\n", 0, 0, 0);
+ if(remove_hash(cache->c_dntable, (void *)newndn, strlen(newndn)) == 0){
+ LOG("entry cache replace: failed to remove dn table(uuid cache)\n", 0, 0, 0);
+ }
+ if(remove_hash(cache->c_idtable, &(newe->ep_id), sizeof(ID)) == 0){
+ LOG("entry cache replace: failed to remove id table(uuid cache)\n", 0, 0, 0);
+ }
+ cache_unlock(cache);
+ return 1;
}
#endif
/* adjust cache meta info */
@@ -1110,7 +1110,7 @@ static int entrycache_replace(struct cache *cache, struct backentry *olde,
slapi_counter_subtract(cache->c_cursize, olde->ep_size - newe->ep_size);
}
newe->ep_state = 0;
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
LOG("<= entrycache_replace OK, cache size now %lu cache count now %ld\n",
slapi_counter_get_value(cache->c_cursize), cache->c_curentries, 0);
return 0;
@@ -1144,10 +1144,14 @@ entrycache_return(struct cache *cache, struct backentry **bep)
struct backentry *e;
e = *bep;
+ if (!e) {
+ LDAPDebug0Args(LDAP_DEBUG_ANY, "entrycache_return e is NULL\n");
+ return;
+ }
LOG("=> entrycache_return (%s) entry count: %d, entry in cache:%ld\n",
backentry_get_ndn(e), e->ep_refcnt, cache->c_curentries);
- PR_Lock(cache->c_mutex);
+ cache_lock(cache);
if (e->ep_state & ENTRY_STATE_NOTINCACHE)
{
backentry_free(bep);
@@ -1166,7 +1170,7 @@ entrycache_return(struct cache *cache, struct backentry **bep)
}
}
}
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
while (eflush)
{
eflushtemp = BACK_LRU_NEXT(eflush, struct backentry *);
@@ -1185,22 +1189,22 @@ struct backentry *cache_find_dn(struct cache *cache, const char *dn, unsigned lo
LOG("=> cache_find_dn (%s)\n", dn, 0, 0);
/*entry normalized by caller (dn2entry.c) */
- PR_Lock(cache->c_mutex);
+ cache_lock(cache);
if (find_hash(cache->c_dntable, (void *)dn, ndnlen, (void **)&e)) {
/* need to check entry state */
if (e->ep_state != 0) {
/* entry is deleted or not fully created yet */
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
LOG("<= cache_find_dn (NOT FOUND)\n", 0, 0, 0);
return NULL;
}
if (e->ep_refcnt == 0)
lru_delete(cache, (void *)e);
e->ep_refcnt++;
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
slapi_counter_increment(cache->c_hits);
} else {
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
}
slapi_counter_increment(cache->c_tries);
@@ -1216,22 +1220,22 @@ struct backentry *cache_find_id(struct cache *cache, ID id)
LOG("=> cache_find_id (%lu)\n", (u_long)id, 0, 0);
- PR_Lock(cache->c_mutex);
+ cache_lock(cache);
if (find_hash(cache->c_idtable, &id, sizeof(ID), (void **)&e)) {
/* need to check entry state */
if (e->ep_state != 0) {
/* entry is deleted or not fully created yet */
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
LOG("<= cache_find_id (NOT FOUND)\n", 0, 0, 0);
return NULL;
}
if (e->ep_refcnt == 0)
lru_delete(cache, (void *)e);
e->ep_refcnt++;
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
slapi_counter_increment(cache->c_hits);
} else {
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
}
slapi_counter_increment(cache->c_tries);
@@ -1247,22 +1251,22 @@ struct backentry *cache_find_uuid(struct cache *cache, const char *uuid)
LOG("=> cache_find_uuid (%s)\n", uuid, 0, 0);
- PR_Lock(cache->c_mutex);
+ cache_lock(cache);
if (find_hash(cache->c_uuidtable, uuid, strlen(uuid), (void **)&e)) {
/* need to check entry state */
if (e->ep_state != 0) {
/* entry is deleted or not fully created yet */
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
LOG("<= cache_find_uuid (NOT FOUND)\n", 0, 0, 0);
return NULL;
}
if (e->ep_refcnt == 0)
lru_delete(cache, (void *)e);
e->ep_refcnt++;
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
slapi_counter_increment(cache->c_hits);
} else {
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
}
slapi_counter_increment(cache->c_tries);
@@ -1299,7 +1303,7 @@ entrycache_add_int(struct cache *cache, struct backentry *e, int state,
entry_size = e->ep_size;
}
- PR_Lock(cache->c_mutex);
+ cache_lock(cache);
if (! add_hash(cache->c_dntable, (void *)ndn, strlen(ndn), e,
(void **)&my_alt)) {
LOG("entry \"%s\" already in dn cache\n", ndn, 0, 0);
@@ -1334,7 +1338,7 @@ entrycache_add_int(struct cache *cache, struct backentry *e, int state,
* to prevent that the caller accidentally thinks the existing
* entry is not the same one the caller has and releases it.
*/
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
return 1;
}
}
@@ -1344,7 +1348,7 @@ entrycache_add_int(struct cache *cache, struct backentry *e, int state,
{
LOG("the entry %s is reserved (ep_state: 0x%x, state: 0x%x)\n", ndn, e->ep_state, state);
e->ep_state |= ENTRY_STATE_NOTINCACHE;
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
return -1;
}
else if (state != 0)
@@ -1352,7 +1356,7 @@ entrycache_add_int(struct cache *cache, struct backentry *e, int state,
LOG("the entry %s already exists. cannot reserve it. (ep_state: 0x%x, state: 0x%x)\n",
ndn, e->ep_state, state);
e->ep_state |= ENTRY_STATE_NOTINCACHE;
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
return -1;
}
else
@@ -1364,12 +1368,14 @@ entrycache_add_int(struct cache *cache, struct backentry *e, int state,
(*alt)->ep_refcnt++;
LOG("the entry %s already exists. returning existing entry %s (state: 0x%x)\n",
ndn, backentry_get_ndn(my_alt), state);
+ cache_unlock(cache);
+ return 1;
} else {
LOG("the entry %s already exists. Not returning existing entry %s (state: 0x%x)\n",
ndn, backentry_get_ndn(my_alt), state);
+ cache_unlock(cache);
+ return -1;
}
- PR_Unlock(cache->c_mutex);
- return 1;
}
}
}
@@ -1399,14 +1405,14 @@ entrycache_add_int(struct cache *cache, struct backentry *e, int state,
* fine (i think).
*/
LOG("<= entrycache_add_int (ignoring)\n", 0, 0, 0);
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
return 0;
}
if(remove_hash(cache->c_dntable, (void *)ndn, strlen(ndn)) == 0){
LOG("entrycache_add_int: failed to remove %s from dn table\n", 0, 0, 0);
}
e->ep_state |= ENTRY_STATE_NOTINCACHE;
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
LOG("entrycache_add_int: failed to add %s to cache (ep_state: %x, already_in: %d)\n",
ndn, e->ep_state, already_in);
return -1;
@@ -1425,7 +1431,7 @@ entrycache_add_int(struct cache *cache, struct backentry *e, int state,
LOG("entrycache_add_int: failed to remove id table(uuid cache)\n", 0, 0, 0);
}
e->ep_state |= ENTRY_STATE_NOTINCACHE;
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
return -1;
}
}
@@ -1450,7 +1456,7 @@ entrycache_add_int(struct cache *cache, struct backentry *e, int state,
if (CACHE_FULL(cache))
eflush = entrycache_flush(cache);
}
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
while (eflush)
{
@@ -1502,11 +1508,11 @@ int cache_add_tentative(struct cache *cache, struct backentry *e,
}
void cache_lock(struct cache *cache)
{
- PR_Lock(cache->c_mutex);
+ PR_EnterMonitor(cache->c_mutex);
}
void cache_unlock(struct cache *cache)
{
- PR_Unlock(cache->c_mutex);
+ PR_ExitMonitor(cache->c_mutex);
}
/* locks an entry so that it can be modified (you should have gotten the
@@ -1540,14 +1546,14 @@ int cache_lock_entry(struct cache *cache, struct backentry *e)
PR_EnterMonitor(e->ep_mutexp);
/* make sure entry hasn't been deleted now */
- PR_Lock(cache->c_mutex);
+ cache_lock(cache);
if (e->ep_state & (ENTRY_STATE_DELETED|ENTRY_STATE_NOTINCACHE)) {
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
PR_ExitMonitor(e->ep_mutexp);
LOG("<= cache_lock_entry (DELETED)\n", 0, 0, 0);
return RETRY_CACHE_LOCK;
}
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
LOG("<= cache_lock_entry (FOUND)\n", 0, 0, 0);
return 0;
@@ -1613,7 +1619,7 @@ dncache_set_max_size(struct cache *cache, size_t bytes)
"WARNING -- Minimum cache size is %lu -- rounding up\n",
MINCACHESIZE, 0, 0);
}
- PR_Lock(cache->c_mutex);
+ cache_lock(cache);
cache->c_maxsize = bytes;
LOG("entry cache size set to %lu\n", bytes, 0, 0);
/* check for full cache, and clear out if necessary */
@@ -1633,7 +1639,7 @@ dncache_set_max_size(struct cache *cache, size_t bytes)
erase_cache(cache, CACHE_TYPE_DN);
cache_make_hashes(cache, CACHE_TYPE_DN);
}
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
if (! dblayer_is_cachesize_sane(&bytes)) {
LDAPDebug1Arg(LDAP_DEBUG_ANY,
"WARNING -- Possible CONFIGURATION ERROR -- cachesize "
@@ -1697,7 +1703,7 @@ dncache_return(struct cache *cache, struct backdn **bdn)
LOG("=> dncache_return (%s) reference count: %d, dn in cache:%ld\n",
slapi_sdn_get_dn((*bdn)->dn_sdn), (*bdn)->ep_refcnt, cache->c_curentries);
- PR_Lock(cache->c_mutex);
+ cache_lock(cache);
if ((*bdn)->ep_state & ENTRY_STATE_NOTINCACHE)
{
backdn_free(bdn);
@@ -1717,7 +1723,7 @@ dncache_return(struct cache *cache, struct backdn **bdn)
}
}
}
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
while (dnflush)
{
dnflushtemp = BACK_LRU_NEXT(dnflush, struct backdn *);
@@ -1738,22 +1744,22 @@ dncache_find_id(struct cache *cache, ID id)
LOG("=> dncache_find_id (%lu)\n", (u_long)id, 0, 0);
- PR_Lock(cache->c_mutex);
+ cache_lock(cache);
if (find_hash(cache->c_idtable, &id, sizeof(ID), (void **)&bdn)) {
/* need to check entry state */
if (bdn->ep_state != 0) {
/* entry is deleted or not fully created yet */
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
LOG("<= dncache_find_id (NOT FOUND)\n", 0, 0, 0);
return NULL;
}
if (bdn->ep_refcnt == 0)
lru_delete(cache, (void *)bdn);
bdn->ep_refcnt++;
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
slapi_counter_increment(cache->c_hits);
} else {
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
}
slapi_counter_increment(cache->c_tries);
@@ -1778,7 +1784,7 @@ dncache_add_int(struct cache *cache, struct backdn *bdn, int state,
LOG("=> dncache_add_int( \"%s\", %ld )\n", slapi_sdn_get_dn(bdn->dn_sdn),
bdn->ep_id, 0);
- PR_Lock(cache->c_mutex);
+ cache_lock(cache);
if (! add_hash(cache->c_idtable, &(bdn->ep_id), sizeof(ID), bdn,
(void **)&my_alt)) {
@@ -1813,7 +1819,7 @@ dncache_add_int(struct cache *cache, struct backdn *bdn, int state,
* to prevent that the caller accidentally thinks the existing
* entry is not the same one the caller has and releases it.
*/
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
return 1;
}
}
@@ -1823,14 +1829,14 @@ dncache_add_int(struct cache *cache, struct backdn *bdn, int state,
{
LOG("the entry is reserved\n", 0, 0, 0);
bdn->ep_state |= ENTRY_STATE_NOTINCACHE;
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
return -1;
}
else if (state != 0)
{
LOG("the entry already exists. cannot reserve it.\n", 0, 0, 0);
bdn->ep_state |= ENTRY_STATE_NOTINCACHE;
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
return -1;
}
else
@@ -1841,7 +1847,7 @@ dncache_add_int(struct cache *cache, struct backdn *bdn, int state,
lru_delete(cache, (void *)*alt);
(*alt)->ep_refcnt++;
}
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
return 1;
}
}
@@ -1870,7 +1876,7 @@ dncache_add_int(struct cache *cache, struct backdn *bdn, int state,
dnflush = dncache_flush(cache);
}
}
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
while (dnflush)
{
@@ -1898,7 +1904,7 @@ dncache_replace(struct cache *cache, struct backdn *olddn, struct backdn *newdn)
* where the entry isn't in all the table yet, so we don't care if any
* of these return errors.
*/
- PR_Lock(cache->c_mutex);
+ cache_lock(cache);
/*
* First, remove the old entry from the hashtable.
@@ -1910,7 +1916,7 @@ dncache_replace(struct cache *cache, struct backdn *olddn, struct backdn *newdn)
found = remove_hash(cache->c_idtable, &(olddn->ep_id), sizeof(ID));
if (!found) {
LOG("dn cache replace: cache index tables out of sync\n", 0, 0, 0);
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
return 1;
}
}
@@ -1921,7 +1927,7 @@ dncache_replace(struct cache *cache, struct backdn *olddn, struct backdn *newdn)
*/
if (!add_hash(cache->c_idtable, &(newdn->ep_id), sizeof(ID), newdn, NULL)) {
LOG("dn cache replace: can't add id\n", 0, 0, 0);
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
return 1;
}
/* adjust cache meta info */
@@ -1936,7 +1942,7 @@ dncache_replace(struct cache *cache, struct backdn *olddn, struct backdn *newdn)
}
olddn->ep_state = ENTRY_STATE_DELETED;
newdn->ep_state = 0;
- PR_Unlock(cache->c_mutex);
+ cache_unlock(cache);
LOG("<= dncache_replace OK, cache size now %lu cache count now %ld\n",
slapi_counter_get_value(cache->c_cursize), cache->c_curentries, 0);
return 0;
@@ -2022,23 +2028,24 @@ dn_lru_verify(struct cache *cache, struct backdn *dn, int in)
#ifdef CACHE_DEBUG
void
-check_entry_cache(struct cache *cache, struct backentry *e, int in_cache)
+check_entry_cache(struct cache *cache, struct backentry *e)
{
Slapi_DN *sdn = slapi_entry_get_sdn(e->ep_entry);
struct backentry *debug_e = cache_find_dn(cache,
slapi_sdn_get_dn(sdn),
slapi_sdn_get_ndn_len(sdn));
+ in_cache = cache_is_in_cache(cache, (void *)e);
if (in_cache) {
if (debug_e) { /* e is in cache */
CACHE_RETURN(cache, &debug_e);
if ((e != debug_e) && !(e->ep_state & ENTRY_STATE_DELETED)) {
- slapi_log_error(SLAPI_LOG_FATAL, "ldbm_back_delete",
+ slapi_log_error(SLAPI_LOG_FATAL, "check_entry_cache",
"entry 0x%p is not in dn cache but 0x%p having the same dn %s is "
"although in_cache flag is set!!!\n",
e, debug_e, slapi_sdn_get_dn(sdn));
}
} else if (!(e->ep_state & ENTRY_STATE_DELETED)) {
- slapi_log_error(SLAPI_LOG_FATAL, "ldbm_back_delete",
+ slapi_log_error(SLAPI_LOG_FATAL, "check_entry_cache",
"%s (id %d) is not in dn cache although in_cache flag is set!!!\n",
slapi_sdn_get_dn(sdn), e->ep_id);
}
@@ -2046,13 +2053,13 @@ check_entry_cache(struct cache *cache, struct backentry *e, int in_cache)
if (debug_e) { /* e is in cache */
CACHE_RETURN(cache, &debug_e);
if ((e != debug_e) && !(e->ep_state & ENTRY_STATE_DELETED)) {
- slapi_log_error(SLAPI_LOG_FATAL, "ldbm_back_delete",
+ slapi_log_error(SLAPI_LOG_FATAL, "check_entry_cache",
"entry 0x%p is not in id cache but 0x%p having the same id %d is "
"although in_cache flag is set!!!\n",
e, debug_e, e->ep_id);
}
} else {
- slapi_log_error(SLAPI_LOG_CACHE, "ldbm_back_delete",
+ slapi_log_error(SLAPI_LOG_CACHE, "check_entry_cache",
"%s (id %d) is not in id cache although in_cache flag is set!!!\n",
slapi_sdn_get_dn(sdn), e->ep_id);
}
@@ -2060,7 +2067,7 @@ check_entry_cache(struct cache *cache, struct backentry *e, int in_cache)
if (debug_e) { /* e is in cache */
CACHE_RETURN(cache, &debug_e);
if (e == debug_e) {
- slapi_log_error(SLAPI_LOG_FATAL, "ldbm_back_delete",
+ slapi_log_error(SLAPI_LOG_FATAL, "check_entry_cache",
"%s (id %d) is in dn cache although in_cache flag is not set!!!\n",
slapi_sdn_get_dn(sdn), e->ep_id);
}
@@ -2069,7 +2076,7 @@ check_entry_cache(struct cache *cache, struct backentry *e, int in_cache)
if (debug_e) { /* e is in cache: bad */
CACHE_RETURN(cache, &debug_e);
if (e == debug_e) {
- slapi_log_error(SLAPI_LOG_CACHE, "ldbm_back_delete",
+ slapi_log_error(SLAPI_LOG_CACHE, "check_entry_cache",
"%s (id %d) is in id cache although in_cache flag is not set!!!\n",
slapi_sdn_get_dn(sdn), e->ep_id);
}
@@ -2077,3 +2084,35 @@ check_entry_cache(struct cache *cache, struct backentry *e, int in_cache)
}
}
#endif
+
+int
+cache_has_otherref(struct cache *cache, void *ptr)
+{
+ struct backcommon *bep;
+ int hasref = 0;
+
+ if (NULL == ptr) {
+ return hasref;
+ }
+ bep = (struct backcommon *)ptr;
+ /* slows down too much? PR_Lock(cache->c_mutex); */
+ hasref = bep->ep_refcnt;
+ /* PR_Unlock(cache->c_mutex); */
+ return (hasref>1)?1:0;
+}
+
+int
+cache_is_in_cache(struct cache *cache, void *ptr)
+{
+ struct backcommon *bep;
+ int in_cache = 0;
+
+ if (NULL == ptr) {
+ return in_cache;
+ }
+ bep = (struct backcommon *)ptr;
+ /* slows down too much? PR_Lock(cache->c_mutex); */
+ in_cache = (bep->ep_state & (ENTRY_STATE_DELETED|ENTRY_STATE_NOTINCACHE))?0:1;
+ /* PR_Unlock(cache->c_mutex); */
+ return in_cache;
+}
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_add.c b/ldap/servers/slapd/back-ldbm/ldbm_add.c
index eb11440..2f1b398 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_add.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_add.c
@@ -85,6 +85,7 @@ ldbm_back_add( Slapi_PBlock *pb )
struct backentry *addingentry = NULL;
struct backentry *parententry = NULL;
struct backentry *originalentry = NULL;
+ struct backentry *tmpentry = NULL;
ID pid;
int isroot;
char *errbuf= NULL;
@@ -104,8 +105,6 @@ ldbm_back_add( Slapi_PBlock *pb )
int ruv_c_init = 0;
int rc = 0;
int addingentry_id_assigned = 0;
- int addingentry_in_cache = 0;
- int tombstone_in_cache = 0;
Slapi_DN *sdn = NULL;
Slapi_DN parentsdn;
Slapi_Operation *operation;
@@ -224,34 +223,32 @@ ldbm_back_add( Slapi_PBlock *pb )
dblayer_txn_abort_ext(li, &txn, PR_FALSE);
noabort = 1;
slapi_pblock_set(pb, SLAPI_TXN, parent_txn);
-
- if (addingentry_in_cache) {
+ /* must duplicate addingentry before returning it to cache,
+ * which could free the entry. */
+ if ( (tmpentry = backentry_dup( addingentry )) == NULL ) {
+ ldap_result_code= LDAP_OPERATIONS_ERROR;
+ goto error_return;
+ }
+ if (cache_is_in_cache(&inst->inst_cache, addingentry)) {
/* addingentry is in cache. Remove it once. */
retval = CACHE_REMOVE(&inst->inst_cache, addingentry);
if (retval) {
LDAPDebug1Arg(LDAP_DEBUG_CACHE, "ldbm_add: cache_remove %s failed.\n",
slapi_entry_get_dn_const(addingentry->ep_entry));
}
- CACHE_RETURN(&inst->inst_cache, &addingentry);
- } else {
- backentry_free(&addingentry);
}
+ CACHE_RETURN(&inst->inst_cache, &addingentry);
slapi_pblock_set( pb, SLAPI_ADD_ENTRY, originalentry->ep_entry );
addingentry = originalentry;
- if ( (originalentry = backentry_dup( addingentry )) == NULL ) {
- ldap_result_code= LDAP_OPERATIONS_ERROR;
+ originalentry = tmpentry;
+ tmpentry = NULL;
+ /* Adding the resetted addingentry to the cache. */
+ if (cache_add_tentative(&inst->inst_cache, addingentry, NULL) < 0) {
+ LDAPDebug1Arg(LDAP_DEBUG_CACHE, "cache_add_tentative concurrency detected: %s\n",
+ slapi_entry_get_dn_const(addingentry->ep_entry));
+ ldap_result_code = LDAP_ALREADY_EXISTS;
goto error_return;
}
- if (addingentry_in_cache) {
- /* Adding the resetted addingentry to the cache. */
- if (cache_add_tentative(&inst->inst_cache, addingentry, NULL) != 0) {
- LDAPDebug1Arg(LDAP_DEBUG_CACHE, "cache_add_tentative concurrency detected: %s\n",
- slapi_entry_get_dn_const(addingentry->ep_entry));
- ldap_result_code = LDAP_ALREADY_EXISTS;
- addingentry_in_cache = 0;
- goto error_return;
- }
- }
if (ruv_c_init) {
/* reset the ruv txn stuff */
modify_term(&ruv_c, be);
@@ -533,7 +530,6 @@ ldbm_back_add( Slapi_PBlock *pb )
ldap_result_code= -1;
goto error_return; /* error result sent by find_entry2modify() */
}
- tombstone_in_cache = 1;
addingentry = backentry_dup( tombstoneentry );
if ( addingentry==NULL )
@@ -811,14 +807,13 @@ ldbm_back_add( Slapi_PBlock *pb )
/* Tentatively add the entry to the cache. We do this after adding any
* operational attributes to ensure that the cache is sized correctly. */
- if ( cache_add_tentative( &inst->inst_cache, addingentry, NULL ) != 0 )
+ if ( cache_add_tentative( &inst->inst_cache, addingentry, NULL ) < 0 )
{
LDAPDebug1Arg(LDAP_DEBUG_CACHE, "cache_add_tentative concurrency detected: %s\n",
slapi_entry_get_dn_const(addingentry->ep_entry));
ldap_result_code= LDAP_ALREADY_EXISTS;
goto error_return;
}
- addingentry_in_cache = 1;
/*
* Before we add the entry, find out if the syntax of the aci
@@ -853,7 +848,6 @@ ldbm_back_add( Slapi_PBlock *pb )
parent_found = 1;
parententry = NULL;
}
-
if ( (originalentry = backentry_dup(addingentry )) == NULL ) {
ldap_result_code= LDAP_OPERATIONS_ERROR;
goto error_return;
@@ -888,7 +882,7 @@ ldbm_back_add( Slapi_PBlock *pb )
goto error_return;
}
- retval = id2entry_add( be, addingentry, &txn );
+ retval = id2entry_add_ext(be, addingentry, &txn, 1, &myrc);
if (DB_LOCK_DEADLOCK == retval)
{
LDAPDebug( LDAP_DEBUG_ARGS, "add 1 DEADLOCK\n", 0, 0, 0 );
@@ -1136,10 +1130,6 @@ ldbm_back_add( Slapi_PBlock *pb )
retval = -1;
goto error_return;
}
- if (addingentry_in_cache) { /* decrease the refcnt added by tentative */
- CACHE_RETURN( &inst->inst_cache, &addingentry );
- }
- addingentry_in_cache = 1; /* reset it to make it sure... */
/*
* The tombstone was locked down in the cache... we can
* get rid of the entry in the cache now.
@@ -1154,9 +1144,6 @@ ldbm_back_add( Slapi_PBlock *pb )
CACHE_RETURN(&inst->inst_dncache, &bdn);
}
}
- cache_unlock_entry(&inst->inst_cache, tombstoneentry);
- CACHE_RETURN(&inst->inst_cache, &tombstoneentry);
- tombstone_in_cache = 0;
}
if (parent_found)
{
@@ -1224,21 +1211,18 @@ error_return:
}
if ( addingentry )
{
- if ( addingentry_in_cache )
- {
- if (inst) {
- CACHE_REMOVE(&inst->inst_cache, addingentry);
- /* tell frontend not to free this entry */
- slapi_pblock_set(pb, SLAPI_ADD_ENTRY, NULL);
- }
+ if (inst && cache_is_in_cache(&inst->inst_cache, addingentry)) {
+ CACHE_REMOVE(&inst->inst_cache, addingentry);
+ /* tell frontend not to free this entry */
+ slapi_pblock_set(pb, SLAPI_ADD_ENTRY, NULL);
}
- else
+ else if (!cache_has_otherref(&inst->inst_cache, addingentry))
{
if (!is_resurect_operation) { /* if resurect, tombstoneentry is dupped. */
backentry_clear_entry(addingentry); /* e is released in the frontend */
}
- backentry_free( &addingentry ); /* release the backend wrapper, here */
}
+ CACHE_RETURN( &inst->inst_cache, &addingentry );
}
if (rc == DB_RUNRECOVERY) {
dblayer_remember_disk_filled(li);
@@ -1291,12 +1275,6 @@ diskfull_return:
opreturn = -1;
slapi_pblock_set(pb, SLAPI_PLUGIN_OPRETURN, &opreturn);
}
- if (addingentry_in_cache && addingentry && inst) {
- CACHE_REMOVE(&inst->inst_cache, addingentry);
- /* tell frontend not to free this entry */
- slapi_pblock_set(pb, SLAPI_ADD_ENTRY, NULL);
- }
-
slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, &ldap_result_message);
}
@@ -1314,11 +1292,11 @@ diskfull_return:
common_return:
if (inst) {
- if(tombstone_in_cache && tombstoneentry) {
+ if (tombstoneentry && cache_is_in_cache(&inst->inst_cache, tombstoneentry)) {
cache_unlock_entry(&inst->inst_cache, tombstoneentry);
CACHE_RETURN(&inst->inst_cache, &tombstoneentry);
}
- if (addingentry_in_cache && addingentry) {
+ if (addingentry) {
if ((0 == retval) && entryrdn_get_switch()) { /* subtree-rename: on */
/* since adding the entry to the entry cache was successful,
* let's add the dn to dncache, if not yet done. */
@@ -1373,6 +1351,7 @@ common_return:
slapi_send_ldap_result( pb, ldap_result_code, ldap_result_matcheddn, ldap_result_message, 0, NULL );
}
backentry_free(&originalentry);
+ backentry_free(&tmpentry);
slapi_sdn_done(&parentsdn);
slapi_ch_free( (void**)&ldap_result_matcheddn );
slapi_ch_free( (void**)&errbuf );
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_delete.c b/ldap/servers/slapd/back-ldbm/ldbm_delete.c
index a00989e..5f12ea3 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_delete.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_delete.c
@@ -61,6 +61,7 @@ ldbm_back_delete( Slapi_PBlock *pb )
struct backentry *e = NULL;
struct backentry *tombstone = NULL;
struct backentry *original_tombstone = NULL;
+ struct backentry *tmptombstone = NULL;
const char *dn = NULL;
back_txn txn;
back_txnid parent_txn;
@@ -88,8 +89,6 @@ ldbm_back_delete( Slapi_PBlock *pb )
int delete_tombstone_entry = 0; /* We must remove the given tombstone entry from the DB */
int create_tombstone_entry = 0; /* We perform a "regular" LDAP delete but since we use */
/* replication, we must create a new tombstone entry */
- int tombstone_in_cache = 0;
- int e_in_cache = 0;
int remove_e_from_cache = 0;
entry_address *addr;
int addordel_flags = 0; /* passed to index_addordel */
@@ -105,6 +104,8 @@ ldbm_back_delete( Slapi_PBlock *pb )
const CSN *tombstone_csn = NULL;
char deletion_csn_str[CSN_STRSIZE];
int op_id;
+ ID ep_id = 0;
+ ID tomb_ep_id = 0;
if (slapi_pblock_get(pb, SLAPI_CONN_ID, &conn_id) < 0) {
conn_id = 0; /* connection is NULL */
@@ -207,7 +208,7 @@ ldbm_back_delete( Slapi_PBlock *pb )
*/
txn.back_txn_txn = NULL; /* ready to create the child transaction */
for (retry_count = 0; retry_count < RETRY_TIMES; retry_count++) {
- if (txn.back_txn_txn && (txn.back_txn_txn != parent_txn)) {
+ if (txn.back_txn_txn && (txn.back_txn_txn != parent_txn)) { /* retry_count > 0 */
Slapi_Entry *ent = NULL;
/* Don't release SERIAL LOCK */
@@ -228,25 +229,30 @@ ldbm_back_delete( Slapi_PBlock *pb )
/* reset tombstone entry */
if (original_tombstone) {
- if (tombstone_in_cache) {
- CACHE_REMOVE(&inst->inst_cache, tombstone);
- CACHE_RETURN(&inst->inst_cache, &tombstone);
- tombstone = NULL;
- tombstone_in_cache = 0;
- } else {
- backentry_free(&tombstone);
- }
- tombstone = original_tombstone;
- if ( (original_tombstone = backentry_dup( tombstone )) == NULL ) {
+ /* must duplicate tombstone before returning it to cache,
+ * which could free the entry. */
+ if ( (tmptombstone = backentry_dup( original_tombstone )) == NULL ) {
ldap_result_code= LDAP_OPERATIONS_ERROR;
goto error_return;
}
+ if (cache_is_in_cache(&inst->inst_cache, tombstone)) {
+ CACHE_REMOVE(&inst->inst_cache, tombstone);
+ }
+ CACHE_RETURN(&inst->inst_cache, &tombstone);
+ if (tombstone) {
+ slapi_log_error(SLAPI_LOG_FATAL, "ldbm_back_delete",
+ "conn=%lu op=%d [retry: %d] tombstone %s is not freed!!! refcnt %d, state %d\n",
+ conn_id, op_id, retry_count, slapi_entry_get_dn(tombstone->ep_entry),
+ tombstone->ep_refcnt, tombstone->ep_state);
+ }
+ tombstone = original_tombstone;
+ original_tombstone = tmptombstone;
+ tmptombstone = NULL;
+ } else {
+ slapi_log_error(SLAPI_LOG_FATAL, "ldbm_back_delete",
+ "conn=%lu op=%d [retry: %d] No original_tombstone for %s!!\n",
+ conn_id, op_id, retry_count, slapi_entry_get_dn(e->ep_entry));
}
- /* reset original entry in cache */
- if (!e_in_cache) {
- CACHE_ADD(&inst->inst_cache, e, NULL);
- e_in_cache = 1;
- }
if (ruv_c_init) {
/* reset the ruv txn stuff */
modify_term(&ruv_c, be);
@@ -254,8 +260,7 @@ ldbm_back_delete( Slapi_PBlock *pb )
}
/* We're re-trying */
- LDAPDebug0Args(LDAP_DEBUG_BACKLDBM,
- "Delete Retrying Transaction\n");
+ LDAPDebug0Args(LDAP_DEBUG_BACKLDBM, "Delete Retrying Transaction\n");
#ifndef LDBM_NO_BACKOFF_DELAY
{
PRIntervalTime interval;
@@ -297,12 +302,11 @@ ldbm_back_delete( Slapi_PBlock *pb )
LDAPDebug0Args(LDAP_DEBUG_BACKLDBM, "ldbm_back_delete: Deleting entry is already deleted.\n");
goto error_return; /* error result sent by find_entry2modify() */
}
- e_in_cache = 1; /* e is cached */
-
+ ep_id = e->ep_id;
retval = slapi_entry_has_children(e->ep_entry);
if (retval) {
ldap_result_code= LDAP_NOT_ALLOWED_ON_NONLEAF;
- slapi_log_error(SLAPI_LOG_FATAL, "ldbm_back_delete",
+ slapi_log_error(SLAPI_LOG_BACKLDBM, "ldbm_back_delete",
"conn=%lu op=%d Deleting entry %s has %d children.\n",
conn_id, op_id, slapi_entry_get_dn(e->ep_entry), retval);
retval = -1;
@@ -550,12 +554,11 @@ ldbm_back_delete( Slapi_PBlock *pb )
op |= PARENTUPDATE_DELETE_TOMBSTONE;
}
retval = parent_update_on_childchange(&parent_modify_c, op, &haschildren);
- slapi_log_error(SLAPI_LOG_BACKLDBM, "ldbm_back_delete",
- "conn=%lu op=%d parent_update_on_childchange: old_entry=0x%p, new_entry=0x%p, rc=%d\n",
- conn_id, op_id, parent_modify_c.old_entry, parent_modify_c.new_entry, retval);
-
/* The modify context now contains info needed later */
if (0 != retval) {
+ slapi_log_error(SLAPI_LOG_FATAL, "ldbm_back_delete",
+ "conn=%lu op=%d parent_update_on_childchange: old_entry=0x%p, new_entry=0x%p, rc=%d\n",
+ conn_id, op_id, parent_modify_c.old_entry, parent_modify_c.new_entry, retval);
ldap_result_code= LDAP_OPERATIONS_ERROR;
slapi_sdn_done(&parentsdn);
retval = -1;
@@ -612,6 +615,7 @@ ldbm_back_delete( Slapi_PBlock *pb )
parentuniqueid= slapi_entry_get_uniqueid(parent_modify_c.old_entry->ep_entry);
}
tombstone = backentry_dup( e );
+ tomb_ep_id = tombstone->ep_id;
slapi_entry_set_dn(tombstone->ep_entry,tombstone_dn); /* Consumes DN */
if (entryrdn_get_switch()) /* subtree-rename: on */
{
@@ -725,13 +729,10 @@ ldbm_back_delete( Slapi_PBlock *pb )
* entry is removed from the cache.
*/
retval = cache_add_tentative(&inst->inst_cache, tombstone, NULL);
- if (0 == retval) {
- tombstone_in_cache = 1;
- } else {
+ if (0 > retval) {
slapi_log_error(SLAPI_LOG_CACHE, "ldbm_back_delete",
"conn=%lu op=%d tombstone entry %s failed to add to the cache: %d\n",
conn_id, op_id, slapi_entry_get_dn(tombstone->ep_entry), retval);
- tombstone_in_cache = 0;
if (LDBM_OS_ERR_IS_DISKFULL(retval)) disk_full = 1;
DEL_SET_ERROR(ldap_result_code,
LDAP_OPERATIONS_ERROR, retry_count);
@@ -750,61 +751,6 @@ ldbm_back_delete( Slapi_PBlock *pb )
DEL_SET_ERROR(ldap_result_code, LDAP_OPERATIONS_ERROR, retry_count);
goto error_return;
}
- if (tombstone_in_cache) {
- retval = cache_replace(&inst->inst_cache, e, tombstone);
- if (retval) {
- LDAPDebug(LDAP_DEBUG_CACHE, "ldbm_back_delete: cache_replace failed (%d): %s --> %s\n",
- retval, slapi_entry_get_dn(e->ep_entry), slapi_entry_get_dn(tombstone->ep_entry));
- retval= -1;
- DEL_SET_ERROR(ldap_result_code, LDAP_OPERATIONS_ERROR, retry_count);
- goto error_return;
- } else {
- e_in_cache = 0;
- }
- } else {
- struct backentry *imposter = NULL;
- retval = CACHE_ADD(&inst->inst_cache, tombstone, &imposter);
- if (retval > 0) {
- if (imposter) {
- /*
- * The same tombstone entry (different Slapi_Entry) is already
- * generated and set to cache. Back off.
- */
- CACHE_RETURN(&inst->inst_cache, &imposter);
- LDAPDebug1Arg(LDAP_DEBUG_CACHE,
- "ldbm_delete: cache add: same DN tombstone in cache: %s\n",
- slapi_entry_get_dn(tombstone->ep_entry));
- } else {
- /*
- * The same tombstone entry (same Slapi_Entry) is being created.
- * Something is wrong. We should clean it up from the cache,
- * and back off.
- */
- tombstone_in_cache = 1;
- LDAPDebug1Arg(LDAP_DEBUG_CACHE,
- "ldbm_delete: cache add: same tombstone in cache: %s\n",
- slapi_entry_get_dn(tombstone->ep_entry));
- }
- retval= -1;
- DEL_SET_ERROR(ldap_result_code, LDAP_OPERATIONS_ERROR, retry_count);
- goto error_return;
- } else if (retval < 0) {
- LDAPDebug1Arg(LDAP_DEBUG_CACHE,
- "ldbm_delete: cache add: Add %s failed.\n",
- slapi_entry_get_dn(tombstone->ep_entry));
- /* Complete add error */
- retval= -1;
- DEL_SET_ERROR(ldap_result_code, LDAP_OPERATIONS_ERROR, retry_count);
- goto error_return;
- }
- }
- if (tombstone_in_cache) {
- /* tombstone was already added to the cache via cache_add_tentative (to reserve its spot in the cache)
- and/or id2entry_add - so it already had one refcount - cache_replace adds another refcount -
- drop the extra ref added by cache_replace */
- CACHE_RETURN( &inst->inst_cache, &tombstone );
- }
- tombstone_in_cache = 1;
}
else
{
@@ -1266,6 +1212,15 @@ ldbm_back_delete( Slapi_PBlock *pb )
retval = -1;
goto error_return;
}
+ if (create_tombstone_entry) {
+ retval = cache_replace(&inst->inst_cache, e, tombstone);
+ if (retval) {
+ LDAPDebug(LDAP_DEBUG_CACHE, "ldbm_back_delete: cache_replace failed (%d): %s --> %s\n",
+ retval, slapi_entry_get_dn(e->ep_entry), slapi_entry_get_dn(tombstone->ep_entry));
+ retval= -1;
+ goto error_return;
+ }
+ }
/* call the transaction post delete plugins just before the commit */
if (plugin_call_plugins(pb, SLAPI_PLUGIN_BE_TXN_POST_DELETE_FN)) {
@@ -1306,22 +1261,26 @@ ldbm_back_delete( Slapi_PBlock *pb )
/* delete from cache and clean up */
if (e) {
- if (entryrdn_get_switch()) { /* subtree-rename: on */
+ if (cache_is_in_cache(&inst->inst_cache, e)) {
+ ep_id = e->ep_id; /* Otherwise, e might have been freed. */
+ CACHE_REMOVE(&inst->inst_cache, e);
+ }
+ cache_unlock_entry(&inst->inst_cache, e);
+ CACHE_RETURN(&inst->inst_cache, &e);
+ /*
+ * e is unlocked and no longer in cache.
+ * It could be freed at any moment.
+ */
+ e = NULL;
+
+ if (entryrdn_get_switch() && ep_id) { /* subtree-rename: on */
/* since the op was successful, delete the tombstone dn from the dn cache */
- struct backdn *bdn = dncache_find_id(&inst->inst_dncache, e->ep_id);
+ struct backdn *bdn = dncache_find_id(&inst->inst_dncache, ep_id);
if (bdn) { /* in the dncache, remove it. */
CACHE_REMOVE(&inst->inst_dncache, bdn);
CACHE_RETURN(&inst->inst_dncache, &bdn);
}
}
- if (e_in_cache) {
- CACHE_REMOVE(&inst->inst_cache, e);
- cache_unlock_entry(&inst->inst_cache, e);
- CACHE_RETURN(&inst->inst_cache, &e);
- } else {
- cache_unlock_entry(&inst->inst_cache, e);
- }
- e = NULL;
}
if (ruv_c_init) {
@@ -1351,43 +1310,23 @@ ldbm_back_delete( Slapi_PBlock *pb )
error_return:
if (tombstone) {
- if (entryrdn_get_switch()) { /* subtree-rename: on */
+ if (cache_is_in_cache(&inst->inst_cache, tombstone)) {
+ tomb_ep_id = tombstone->ep_id; /* Otherwise, tombstone might have been freed. */
+ }
+ if (entryrdn_get_switch() && tomb_ep_id) { /* subtree-rename: on */
struct backdn *bdn = dncache_find_id(&inst->inst_dncache, tombstone->ep_id);
if (bdn) { /* already in the dncache. Delete it. */
CACHE_REMOVE(&inst->inst_dncache, bdn);
CACHE_RETURN(&inst->inst_dncache, &bdn);
}
}
-#ifdef CACHE_DEBUG
- check_entry_cache(&inst->inst_cache, tombstone, tombstone_in_cache);
-#endif
- if (tombstone_in_cache) { /* successfully replaced */
- CACHE_REMOVE( &inst->inst_cache, tombstone );
- CACHE_RETURN( &inst->inst_cache, &tombstone );
- tombstone = NULL;
- tombstone_in_cache = 0;
- } else {
- backentry_free( &tombstone );
- }
- }
- /* Need to return to cache after post op plugins are called */
- if (e) {
-#ifdef CACHE_DEBUG
- check_entry_cache(&inst->inst_cache, e, e_in_cache);
-#endif
- if (e_in_cache) {
- if (remove_e_from_cache) {
- /* The entry is already transformed to a tombstone. */
- CACHE_REMOVE( &inst->inst_cache, e );
- }
- cache_unlock_entry( &inst->inst_cache, e );
- CACHE_RETURN( &inst->inst_cache, &e );
- } else {
- cache_unlock_entry( &inst->inst_cache, e );
+ if (cache_is_in_cache(&inst->inst_cache, tombstone)) {
+ CACHE_REMOVE(&inst->inst_cache, tombstone);
}
+ CACHE_RETURN( &inst->inst_cache, &tombstone );
+ tombstone = NULL;
}
-
if (retval == DB_RUNRECOVERY) {
dblayer_remember_disk_filled(li);
ldbm_nasty("Delete",79,retval);
@@ -1477,16 +1416,8 @@ common_return:
}
}
}
-#ifdef CACHE_DEBUG
- check_entry_cache(&inst->inst_cache, tombstone, tombstone_in_cache);
-#endif
- if (tombstone_in_cache) { /* successfully replaced */
- CACHE_RETURN( &inst->inst_cache, &tombstone );
- tombstone = NULL;
- tombstone_in_cache = 0;
- } else {
- backentry_free( &tombstone );
- }
+ CACHE_RETURN( &inst->inst_cache, &tombstone );
+ tombstone = NULL;
}
/* result code could be used in the bepost plugin functions. */
@@ -1498,6 +1429,22 @@ common_return:
if (!delete_tombstone_entry) {
plugin_call_plugins (pb, SLAPI_PLUGIN_BE_POST_DELETE_FN);
}
+ /* Need to return to cache after post op plugins are called */
+ if (e) {
+ if (cache_is_in_cache(&inst->inst_cache, e)) {
+ if (remove_e_from_cache) {
+ /* The entry is already transformed to a tombstone. */
+ CACHE_REMOVE( &inst->inst_cache, e );
+ }
+ }
+ cache_unlock_entry( &inst->inst_cache, e );
+ CACHE_RETURN( &inst->inst_cache, &e );
+ /*
+ * e is unlocked and no longer in cache.
+ * It could be freed at any moment.
+ */
+ e = NULL;
+ }
if (inst && inst->inst_ref_count) {
slapi_counter_decrement(inst->inst_ref_count);
}
@@ -1516,7 +1463,8 @@ diskfull_return:
}
slapi_log_error(SLAPI_LOG_BACKLDBM, "ldbm_back_delete",
"conn=%lu op=%d modify_term: old_entry=0x%p, new_entry=0x%p, in_cache=%d\n",
- conn_id, op_id, parent_modify_c.old_entry, parent_modify_c.new_entry, parent_modify_c.new_entry_in_cache);
+ conn_id, op_id, parent_modify_c.old_entry, parent_modify_c.new_entry,
+ cache_is_in_cache(&inst->inst_cache, parent_modify_c.new_entry));
myrc = modify_term(&parent_modify_c, be);
if (rc == 0 && opcsn && !is_fixup_operation && !delete_tombstone_entry)
{
@@ -1534,6 +1482,7 @@ diskfull_return:
slapi_pblock_set(pb, SLAPI_DELETE_EXISTING_ENTRY, NULL);
}
backentry_free(&original_tombstone);
+ backentry_free(&tmptombstone);
slapi_ch_free((void**)&errbuf);
slapi_sdn_done(&nscpEntrySDN);
slapi_ch_free_string(&e_uniqueid);
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modify.c b/ldap/servers/slapd/back-ldbm/ldbm_modify.c
index 3dba6f3..254ef29 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_modify.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_modify.c
@@ -65,7 +65,6 @@ void modify_init(modify_context *mc,struct backentry *old_entry)
PR_ASSERT(NULL == mc->new_entry);
mc->old_entry = old_entry;
- mc->new_entry_in_cache = 0;
mc->attr_encrypt = 1;
}
@@ -86,6 +85,9 @@ int modify_apply_mods_ignore_error(modify_context *mc, Slapi_Mods *smods, int er
ret = entry_apply_mods_ignore_error( mc->new_entry->ep_entry, slapi_mods_get_ldapmods_byref(smods), error);
}
mc->smods= smods;
+ if (error == ret) {
+ ret = LDAP_SUCCESS;
+ }
return ret;
}
@@ -96,16 +98,13 @@ int modify_term(modify_context *mc,struct backend *be)
slapi_mods_free(&mc->smods);
/* Unlock and return entries */
- if (NULL != mc->old_entry) {
+ if (mc->old_entry) {
cache_unlock_entry(&inst->inst_cache, mc->old_entry);
CACHE_RETURN( &(inst->inst_cache), &(mc->old_entry) );
mc->old_entry= NULL;
}
- if (mc->new_entry_in_cache) {
- CACHE_RETURN( &(inst->inst_cache), &(mc->new_entry) );
- } else {
- backentry_free(&(mc->new_entry));
- }
+
+ CACHE_RETURN(&(inst->inst_cache), &(mc->new_entry));
mc->new_entry= NULL;
return 0;
}
@@ -115,11 +114,9 @@ int modify_switch_entries(modify_context *mc,backend *be)
{
ldbm_instance *inst = (ldbm_instance *) be->be_instance_info;
int ret = 0;
- if (mc->old_entry!=NULL && mc->new_entry!=NULL) {
+ if (mc->old_entry && mc->new_entry) {
ret = cache_replace(&(inst->inst_cache), mc->old_entry, mc->new_entry);
- if (ret == 0) {
- mc->new_entry_in_cache = 1;
- } else {
+ if (ret) {
LDAPDebug(LDAP_DEBUG_CACHE, "modify_switch_entries: replacing %s with %s failed (%d)\n",
slapi_entry_get_dn(mc->old_entry->ep_entry),
slapi_entry_get_dn(mc->new_entry->ep_entry), ret);
@@ -140,13 +137,19 @@ modify_unswitch_entries(modify_context *mc,backend *be)
ldbm_instance *inst = (ldbm_instance *) be->be_instance_info;
int ret = 0;
- if (mc->old_entry && mc->new_entry && mc->new_entry_in_cache) {
+ if (mc->old_entry && mc->new_entry &&
+ cache_is_in_cache(&inst->inst_cache, mc->new_entry)) {
/* switch the entries, and reset the new, new, entry */
tmp_be = mc->new_entry;
mc->new_entry = mc->old_entry;
mc->new_entry->ep_state = 0;
- mc->new_entry->ep_refcnt = 0;
- mc->new_entry_in_cache = 0;
+ if (cache_has_otherref(&(inst->inst_cache), mc->new_entry)) {
+ /* some other thread refers the entry */
+ CACHE_RETURN(&(inst->inst_cache), &(mc->new_entry));
+ } else {
+ /* don't call CACHE_RETURN, that frees the entry! */
+ mc->new_entry->ep_refcnt = 0;
+ }
mc->old_entry = tmp_be;
ret = cache_replace(&(inst->inst_cache), mc->old_entry, mc->new_entry);
@@ -157,9 +160,7 @@ modify_unswitch_entries(modify_context *mc,backend *be)
* "old" one. modify_term() will then return the "new" entry.
*/
cache_unlock_entry(&inst->inst_cache, mc->new_entry);
- CACHE_RETURN( &(inst->inst_cache), &(mc->old_entry) );
- mc->new_entry_in_cache = 1;
- mc->old_entry = NULL;
+ cache_lock_entry(&inst->inst_cache, mc->old_entry);
} else {
LDAPDebug(LDAP_DEBUG_CACHE, "modify_unswitch_entries: replacing %s with %s failed (%d)\n",
slapi_entry_get_dn(mc->old_entry->ep_entry),
@@ -391,7 +392,8 @@ ldbm_back_modify( Slapi_PBlock *pb )
backend *be;
ldbm_instance *inst = NULL;
struct ldbminfo *li;
- struct backentry *e = NULL, *ec = NULL, *original_entry = NULL;
+ struct backentry *e = NULL, *ec = NULL;
+ struct backentry *original_entry = NULL, *tmpentry = NULL;
Slapi_Entry *postentry = NULL;
LDAPMod **mods = NULL;
LDAPMod **mods_original = NULL;
@@ -410,7 +412,6 @@ ldbm_back_modify( Slapi_PBlock *pb )
int rc = 0;
Slapi_Operation *operation;
entry_address *addr;
- int ec_in_cache = 0;
int is_fixup_operation= 0;
int is_ruv = 0; /* True if the current entry is RUV */
CSN *opcsn = NULL;
@@ -515,14 +516,22 @@ ldbm_back_modify( Slapi_PBlock *pb )
slapi_pblock_get(pb, SLAPI_MODIFY_MODS, &mods);
ldap_mods_free(mods, 1);
slapi_pblock_set(pb, SLAPI_MODIFY_MODS, copy_mods(mods_original));
- /* ec is not really added to the cache until cache_replace, so we
- don't have to worry about the cache here */
- backentry_free(&ec);
- slapi_pblock_set( pb, SLAPI_MODIFY_EXISTING_ENTRY, original_entry->ep_entry );
- ec = original_entry;
- if ( (original_entry = backentry_dup( ec )) == NULL ) {
- ldap_result_code= LDAP_OPERATIONS_ERROR;
- goto error_return;
+
+ /* reset ec set cache in id2entry_add_ext */
+ if (ec) {
+ /* must duplicate ec before returning it to cache,
+ * which could free the entry. */
+ if ( (tmpentry = backentry_dup( ec )) == NULL ) {
+ ldap_result_code= LDAP_OPERATIONS_ERROR;
+ goto error_return;
+ }
+ if (cache_is_in_cache(&inst->inst_cache, ec)) {
+ CACHE_REMOVE(&inst->inst_cache, ec);
+ }
+ CACHE_RETURN(&inst->inst_cache, &ec);
+ ec = original_entry;
+ original_entry = tmpentry;
+ tmpentry = NULL;
}
if (ruv_c_init) {
@@ -811,15 +820,12 @@ ldbm_back_modify( Slapi_PBlock *pb )
goto error_return;
}
/* e uncached */
- /* we must return both e (which has been deleted) and new entry ec */
- /* cache_replace removes e from the caches */
+ /* we must return both e (which has been deleted) and new entry ec to cache */
+ /* cache_replace removes e from the cache hash tables */
cache_unlock_entry( &inst->inst_cache, e );
CACHE_RETURN( &inst->inst_cache, &e );
-
/* lock new entry in cache to prevent usage until we are complete */
cache_lock_entry( &inst->inst_cache, ec );
- ec_in_cache = 1;
-
postentry = slapi_entry_dup( ec->ep_entry );
slapi_pblock_set( pb, SLAPI_ENTRY_POST_OP, postentry );
@@ -925,11 +931,11 @@ error_return:
}
/* if ec is in cache, remove it, then add back e if we still have it */
- if (inst && ec_in_cache) {
+ if (inst && cache_is_in_cache(&inst->inst_cache, ec)) {
CACHE_REMOVE( &inst->inst_cache, ec );
/* if ec was in cache, e was not - add back e */
if (e) {
- if (CACHE_ADD( &inst->inst_cache, e, NULL )) {
+ if (CACHE_ADD( &inst->inst_cache, e, NULL ) < 0) {
LDAPDebug1Arg(LDAP_DEBUG_CACHE, "ldbm_modify: CACHE_ADD %s failed\n",
slapi_entry_get_dn(e->ep_entry));
}
@@ -940,18 +946,15 @@ common_return:
slapi_mods_done(&smods);
if (inst) {
- if (ec_in_cache) {
- cache_unlock_entry( &inst->inst_cache, ec);
- CACHE_RETURN( &inst->inst_cache, &ec );
- } else {
- backentry_free(&ec);
+ if (cache_is_in_cache(&inst->inst_cache, ec)) {
+ cache_unlock_entry(&inst->inst_cache, ec);
+ } else if (e) {
/* if ec was not in cache, cache_replace was not done.
* i.e., e was not unlocked. */
- if (e) {
- cache_unlock_entry( &inst->inst_cache, e);
- CACHE_RETURN( &inst->inst_cache, &e);
- }
+ cache_unlock_entry(&inst->inst_cache, e);
+ CACHE_RETURN(&inst->inst_cache, &e);
}
+ CACHE_RETURN(&inst->inst_cache, &ec);
if (inst->inst_ref_count) {
slapi_counter_decrement(inst->inst_ref_count);
}
@@ -981,6 +984,7 @@ common_return:
/* free our backups */
ldap_mods_free(mods_original, 1);
backentry_free(&original_entry);
+ backentry_free(&tmpentry);
slapi_ch_free_string(&errbuf);
return rc;
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c b/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
index 3368284..7bcbcee 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
@@ -50,7 +50,7 @@ static void moddn_unlock_and_return_entry(backend *be,struct backentry **targete
static int moddn_newrdn_mods(Slapi_PBlock *pb, const char *olddn, struct backentry *ec, Slapi_Mods *smods_wsi, int is_repl_op);
static IDList *moddn_get_children(back_txn *ptxn, Slapi_PBlock *pb, backend *be, struct backentry *parententry, Slapi_DN *parentdn, struct backentry ***child_entries, struct backdn ***child_dns, int is_resurect_operation);
static int moddn_rename_children(back_txn *ptxn, Slapi_PBlock *pb, backend *be, IDList *children, Slapi_DN *dn_parentdn, Slapi_DN *dn_newsuperiordn, struct backentry *child_entries[]);
-static int modrdn_rename_entry_update_indexes(back_txn *ptxn, Slapi_PBlock *pb, struct ldbminfo *li, struct backentry *e, struct backentry **ec, Slapi_Mods *smods1, Slapi_Mods *smods2, Slapi_Mods *smods3, int *e_in_cache, int *ec_in_cache);
+static int modrdn_rename_entry_update_indexes(back_txn *ptxn, Slapi_PBlock *pb, struct ldbminfo *li, struct backentry *e, struct backentry **ec, Slapi_Mods *smods1, Slapi_Mods *smods2, Slapi_Mods *smods3);
static void mods_remove_nsuniqueid(Slapi_Mods *smods);
#define MOD_SET_ERROR(rc, error, count) \
@@ -67,8 +67,6 @@ ldbm_back_modrdn( Slapi_PBlock *pb )
struct ldbminfo *li;
struct backentry *e= NULL;
struct backentry *ec= NULL;
- int ec_in_cache= 0;
- int e_in_cache= 0;
back_txn txn;
back_txnid parent_txn;
int retval = -1;
@@ -83,8 +81,7 @@ ldbm_back_modrdn( Slapi_PBlock *pb )
struct backentry *parententry= NULL;
struct backentry *newparententry= NULL;
struct backentry *original_entry = NULL;
- struct backentry *original_parent = NULL;
- struct backentry *original_newparent = NULL;
+ struct backentry *tmpentry = NULL;
modify_context parent_modify_context = {0};
modify_context newparent_modify_context = {0};
modify_context ruv_c = {0};
@@ -276,29 +273,22 @@ ldbm_back_modrdn( Slapi_PBlock *pb )
slapi_sdn_free(&dn_newsuperiordn);
slapi_pblock_set(pb, SLAPI_MODRDN_NEWSUPERIOR_SDN, orig_dn_newsuperiordn);
orig_dn_newsuperiordn = slapi_sdn_dup(orig_dn_newsuperiordn);
-#ifdef CACHE_DEBUG
- check_entry_cache(&inst->inst_cache, ec, ec_in_cache);
-#endif
- if (ec_in_cache) {
- /* New entry 'ec' is in the entry cache.
- * Remove it from the cache . */
+ /* must duplicate ec before returning it to cache,
+ * which could free the entry. */
+ if ( (tmpentry = backentry_dup( ec )) == NULL ) {
+ ldap_result_code= LDAP_OPERATIONS_ERROR;
+ goto error_return;
+ }
+ if (cache_is_in_cache(&inst->inst_cache, ec)) {
CACHE_REMOVE(&inst->inst_cache, ec);
- CACHE_RETURN(&inst->inst_cache, &ec);
-#ifdef DEBUG_CACHE
- PR_ASSERT(ec == NULL);
-#endif
- ec_in_cache = 0;
- } else {
- backentry_free(&ec);
}
- /* make sure the original entry is back in the cache if it was removed */
- if (!e_in_cache) {
- if (CACHE_ADD(&inst->inst_cache, e, NULL)) {
+ CACHE_RETURN(&inst->inst_cache, &ec);
+ if (!cache_is_in_cache(&inst->inst_cache, e)) {
+ if (CACHE_ADD(&inst->inst_cache, e, NULL) < 0) {
LDAPDebug1Arg(LDAP_DEBUG_CACHE,
"ldbm_back_modrdn: CACHE_ADD %s to cache failed\n",
slapi_entry_get_dn_const(e->ep_entry));
}
- e_in_cache = 1;
}
slapi_pblock_get( pb, SLAPI_MODRDN_EXISTING_ENTRY, &ent );
if (ent && (ent != original_entry->ep_entry)) {
@@ -306,16 +296,13 @@ ldbm_back_modrdn( Slapi_PBlock *pb )
slapi_pblock_set( pb, SLAPI_MODRDN_EXISTING_ENTRY, NULL );
}
ec = original_entry;
- if ( (original_entry = backentry_dup( ec )) == NULL ) {
- ldap_result_code= LDAP_OPERATIONS_ERROR;
- goto error_return;
- }
+ original_entry = tmpentry;
+ tmpentry = NULL;
slapi_pblock_set( pb, SLAPI_MODRDN_EXISTING_ENTRY, original_entry->ep_entry );
free_modrdn_existing_entry = 0; /* owned by original_entry now */
- if (!ec_in_cache) {
+ if (!cache_is_in_cache(&inst->inst_cache, ec)) {
/* Put the resetted entry 'ec' into the cache again. */
- if (cache_add_tentative( &inst->inst_cache, ec, NULL ) != 0) {
- ec_in_cache = 0; /* not in cache */
+ if (cache_add_tentative( &inst->inst_cache, ec, NULL ) < 0) {
/* allow modrdn even if the src dn and dest dn are identical */
if ( 0 != slapi_sdn_compare((const Slapi_DN *)&dn_newdn,
(const Slapi_DN *)sdn) ) {
@@ -327,8 +314,6 @@ ldbm_back_modrdn( Slapi_PBlock *pb )
}
/* so if the old dn is the same as the new dn, the entry will not be cached
until it is replaced with cache_replace */
- } else {
- ec_in_cache = 1;
}
}
@@ -515,7 +500,6 @@ ldbm_back_modrdn( Slapi_PBlock *pb )
ldap_result_code= -1;
goto error_return; /* error result sent by find_entry2modify() */
}
- e_in_cache = 1; /* e is in the cache and locked */
if (slapi_entry_flag_is_set(e->ep_entry, SLAPI_ENTRY_FLAG_TOMBSTONE) &&
!is_resurect_operation) {
ldap_result_code = LDAP_UNWILLING_TO_PERFORM;
@@ -781,8 +765,7 @@ ldbm_back_modrdn( Slapi_PBlock *pb )
}
/* create it in the cache - prevents others from creating it */
- if (( cache_add_tentative( &inst->inst_cache, ec, NULL ) != 0 ) ) {
- ec_in_cache = 0; /* not in cache */
+ if (( cache_add_tentative( &inst->inst_cache, ec, NULL ) < 0 ) ) {
/* allow modrdn even if the src dn and dest dn are identical */
if ( 0 != slapi_sdn_compare((const Slapi_DN *)&dn_newdn,
(const Slapi_DN *)sdn) ) {
@@ -798,46 +781,41 @@ ldbm_back_modrdn( Slapi_PBlock *pb )
}
/* so if the old dn is the same as the new dn, the entry will not be cached
until it is replaced with cache_replace */
- } else {
- ec_in_cache = 1;
}
-
/* Build the list of modifications required to the existing entry */
+ slapi_mods_init(&smods_generated,4);
+ slapi_mods_init(&smods_generated_wsi,4);
+ ldap_result_code = moddn_newrdn_mods(pb, slapi_sdn_get_ndn(sdn),
+ ec, &smods_generated_wsi, is_replicated_operation);
+ if (ldap_result_code != LDAP_SUCCESS) {
+ if (ldap_result_code == LDAP_UNWILLING_TO_PERFORM)
+ ldap_result_message = "Modification of old rdn attribute type not allowed.";
+ goto error_return;
+ }
+ if (!entryrdn_get_switch()) /* subtree-rename: off */
{
- slapi_mods_init(&smods_generated,4);
- slapi_mods_init(&smods_generated_wsi,4);
- ldap_result_code = moddn_newrdn_mods(pb, slapi_sdn_get_ndn(sdn),
- ec, &smods_generated_wsi, is_replicated_operation);
- if (ldap_result_code != LDAP_SUCCESS) {
- if (ldap_result_code == LDAP_UNWILLING_TO_PERFORM)
- ldap_result_message = "Modification of old rdn attribute type not allowed.";
- goto error_return;
- }
- if (!entryrdn_get_switch()) /* subtree-rename: off */
- {
- /*
- * Remove the old entrydn index entry, and add the new one.
- */
- slapi_mods_add( &smods_generated, LDAP_MOD_DELETE, LDBM_ENTRYDN_STR,
- strlen(backentry_get_ndn(e)), backentry_get_ndn(e));
- slapi_mods_add( &smods_generated, LDAP_MOD_REPLACE, LDBM_ENTRYDN_STR,
- strlen(backentry_get_ndn(ec)), backentry_get_ndn(ec));
- }
-
/*
- * Update parentid if we have a new superior.
- */
- if(slapi_sdn_get_dn(dn_newsuperiordn)!=NULL) {
- char buf[40]; /* Enough for an ID */
-
- if (parententry != NULL) {
- sprintf( buf, "%lu", (u_long)parententry->ep_id );
- slapi_mods_add_string(&smods_generated, LDAP_MOD_DELETE, LDBM_PARENTID_STR, buf);
- }
- if (newparententry != NULL) {
- sprintf( buf, "%lu", (u_long)newparententry->ep_id );
- slapi_mods_add_string(&smods_generated, LDAP_MOD_REPLACE, LDBM_PARENTID_STR, buf);
- }
+ * Remove the old entrydn index entry, and add the new one.
+ */
+ slapi_mods_add( &smods_generated, LDAP_MOD_DELETE, LDBM_ENTRYDN_STR,
+ strlen(backentry_get_ndn(e)), backentry_get_ndn(e));
+ slapi_mods_add( &smods_generated, LDAP_MOD_REPLACE, LDBM_ENTRYDN_STR,
+ strlen(backentry_get_ndn(ec)), backentry_get_ndn(ec));
+ }
+
+ /*
+ * Update parentid if we have a new superior.
+ */
+ if(slapi_sdn_get_dn(dn_newsuperiordn)!=NULL) {
+ char buf[40]; /* Enough for an ID */
+
+ if (parententry != NULL) {
+ sprintf( buf, "%lu", (u_long)parententry->ep_id );
+ slapi_mods_add_string(&smods_generated, LDAP_MOD_DELETE, LDBM_PARENTID_STR, buf);
+ }
+ if (newparententry != NULL) {
+ sprintf( buf, "%lu", (u_long)newparententry->ep_id );
+ slapi_mods_add_string(&smods_generated, LDAP_MOD_REPLACE, LDBM_PARENTID_STR, buf);
}
}
@@ -1063,7 +1041,7 @@ ldbm_back_modrdn( Slapi_PBlock *pb )
/*
* Update the indexes for the entry.
*/
- retval = modrdn_rename_entry_update_indexes(&txn, pb, li, e, &ec, &smods_generated, &smods_generated_wsi, &smods_operation_wsi, &e_in_cache, &ec_in_cache);
+ retval = modrdn_rename_entry_update_indexes(&txn, pb, li, e, &ec, &smods_generated, &smods_generated_wsi, &smods_operation_wsi);
if (DB_LOCK_DEADLOCK == retval)
{
/* Retry txn */
@@ -1506,19 +1484,13 @@ common_return:
}
/* remove the new entry from the cache if the op failed -
otherwise, leave it in */
-#ifdef CACHE_DEBUG
- check_entry_cache(&inst->inst_cache, ec, ec_in_cache);
-#endif
- if (ec_in_cache && ec && inst) {
- if (retval) {
+ if (ec && inst) {
+ if (retval && cache_is_in_cache(&inst->inst_cache, ec)) {
CACHE_REMOVE( &inst->inst_cache, ec );
}
CACHE_RETURN( &inst->inst_cache, &ec );
- } else {
- backentry_free( &ec );
}
ec = NULL;
- ec_in_cache = 0;
}
if (inst) {
@@ -1580,8 +1552,7 @@ common_return:
slapi_ch_free_string(&original_newrdn);
slapi_sdn_free(&orig_dn_newsuperiordn);
backentry_free(&original_entry);
- backentry_free(&original_parent);
- backentry_free(&original_newparent);
+ backentry_free(&tmpentry);
slapi_entry_free(original_targetentry);
slapi_ch_free((void**)&errbuf);
if (retval == 0 && opcsn != NULL && !is_fixup_operation)
@@ -1851,7 +1822,9 @@ mods_remove_nsuniqueid(Slapi_Mods *smods)
* mods contains the list of attribute change made.
*/
static int
-modrdn_rename_entry_update_indexes(back_txn *ptxn, Slapi_PBlock *pb, struct ldbminfo *li, struct backentry *e, struct backentry **ec, Slapi_Mods *smods1, Slapi_Mods *smods2, Slapi_Mods *smods3, int *e_in_cache, int *ec_in_cache)
+modrdn_rename_entry_update_indexes(back_txn *ptxn, Slapi_PBlock *pb, struct ldbminfo *li,
+ struct backentry *e, struct backentry **ec,
+ Slapi_Mods *smods1, Slapi_Mods *smods2, Slapi_Mods *smods3)
{
backend *be;
ldbm_instance *inst;
@@ -1859,7 +1832,6 @@ modrdn_rename_entry_update_indexes(back_txn *ptxn, Slapi_PBlock *pb, struct ldbm
char *msg;
Slapi_Operation *operation;
int is_ruv = 0; /* True if the current entry is RUV */
- int orig_ec_in_cache = 0;
int cache_rc = 0;
slapi_pblock_get( pb, SLAPI_BACKEND, &be );
@@ -1867,7 +1839,6 @@ modrdn_rename_entry_update_indexes(back_txn *ptxn, Slapi_PBlock *pb, struct ldbm
is_ruv = operation_is_flag_set(operation, OP_FLAG_REPL_RUV);
inst = (ldbm_instance *) be->be_instance_info;
- orig_ec_in_cache = *ec_in_cache;
/*
* Update the ID to Entry index.
* Note that id2entry_add replaces the entry, so the Entry ID stays the same.
@@ -1889,7 +1860,6 @@ modrdn_rename_entry_update_indexes(back_txn *ptxn, Slapi_PBlock *pb, struct ldbm
LDAPDebug( LDAP_DEBUG_ANY, "modrdn_rename_entry_update_indexes: id2entry_add failed, err=%d %s\n", retval, (msg = dblayer_strerror( retval )) ? msg : "", 0 );
goto error_return;
}
- *ec_in_cache = 1; /* id2entry_add adds to cache if not already in */
if(smods1!=NULL && slapi_mods_get_num_mods(smods1)>0)
{
/*
@@ -1977,13 +1947,6 @@ modrdn_rename_entry_update_indexes(back_txn *ptxn, Slapi_PBlock *pb, struct ldbm
retval= -1;
goto error_return;
}
- *e_in_cache = 0;
- if (orig_ec_in_cache) {
- /* ec was already added to the cache via cache_add_tentative (to reserve its spot in the cache)
- and/or id2entry_add - so it already had one refcount - cache_replace adds another refcount -
- drop the extra ref added by cache_replace */
- CACHE_RETURN( &inst->inst_cache, ec );
- }
error_return:
return retval;
}
@@ -2018,9 +1981,6 @@ moddn_rename_child_entry(
int olddncomps= 0;
int need= 1; /* For the '\0' */
int i;
- int e_in_cache = 1;
- int ec_in_cache = 0;
-
olddn = slapi_entry_get_dn((*ec)->ep_entry);
if (NULL == olddn) {
return retval;
@@ -2082,8 +2042,7 @@ moddn_rename_child_entry(
* Update all the indexes.
*/
retval = modrdn_rename_entry_update_indexes(ptxn, pb, li, e, ec,
- smodsp, NULL, NULL,
- &e_in_cache, &ec_in_cache);
+ smodsp, NULL, NULL);
/* JCMREPL - Should the children get updated modifiersname and lastmodifiedtime? */
slapi_mods_done(&smods);
}
diff --git a/ldap/servers/slapd/back-ldbm/parents.c b/ldap/servers/slapd/back-ldbm/parents.c
index d375519..f55d527 100644
--- a/ldap/servers/slapd/back-ldbm/parents.c
+++ b/ldap/servers/slapd/back-ldbm/parents.c
@@ -126,11 +126,11 @@ parent_update_on_childchange(modify_context *mc,int op, size_t *new_sub_count )
mod_op = LDAP_MOD_ADD;
} else if (PARENTUPDATE_DEL == op) {
if (!already_present) {
- /* This means that something is wrong---deleting a child but no subcount present on parent */
+ /* This means that there was a conflict. Before coming to this point,
+ * the entry to be deleted was deleted... */
LDAPDebug(LDAP_DEBUG_ANY, "Parent %s has no children. (op 0x%x, repl_op 0x%x)\n",
slapi_entry_get_dn(mc->old_entry->ep_entry), op, repl_op);
slapi_mods_free(&smods);
- PR_ASSERT(0);
return -1;
} else {
if (current_sub_count == 1) {
diff --git a/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h b/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h
index 333179a..01fe915 100644
--- a/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h
+++ b/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h
@@ -88,8 +88,11 @@ int cache_add_tentative(struct cache *cache, struct backentry *e,
int cache_lock_entry(struct cache *cache, struct backentry *e);
void cache_unlock_entry(struct cache *cache, struct backentry *e);
int cache_replace(struct cache *cache, void *oldptr, void *newptr);
+int cache_has_otherref(struct cache *cache, void *bep);
+int cache_is_in_cache(struct cache *cache, void *ptr);
+
#ifdef CACHE_DEBUG
-void check_entry_cache(struct cache *cache, struct backentry *e, int in_cache);
+void check_entry_cache(struct cache *cache, struct backentry *e);
#endif
Hashtable *new_hash(u_long size, u_long offset, HashFn hfn,
9 years, 8 months
admserv/cgi-src40
by Mark Reynolds
admserv/cgi-src40/ds_create.in | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
New commits:
commit e9f3fb9b8ba51a4710129d11f4030a53669dc157
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Fri Aug 22 11:52:23 2014 -0400
Ticket 47665 - Create new instance results in setting wrong ACI for the "cn=config" entry
Bug Description: When creating a new instance, ds_create uses the wrong uid
for the admin user.
Fix Description: If the admin user is not set, then try and query it from the CGI
request, if that fails, then use the current logged in entry.
https://fedorahosted.org/389/ticket/47665
Reviewed by: rmeggins(Thanks!)
diff --git a/admserv/cgi-src40/ds_create.in b/admserv/cgi-src40/ds_create.in
index c91fce4..a922df6 100644
--- a/admserv/cgi-src40/ds_create.in
+++ b/admserv/cgi-src40/ds_create.in
@@ -68,10 +68,16 @@ $inf->{General}->{ConfigDirectoryAdminPwd} = $query->param('cfg_sspt_uid_pw');
$inf->{General}->{AdminDomain} = $query->param('admin_domain') ||
$admConf->{AdminDomain};
-# need to get the admin uid
+# Need to get the admin uid. Start with querying suitespot3x_uid as this should be the admin user
+# ConfigDirectoryAdminID is the current account thats logged in, and it could be the root DN - bad
+# for ACI's
if (!$inf->{admin}->{ServerAdminID}) {
- my @rdns = ldap_explode_dn($inf->{General}->{ConfigDirectoryAdminID}, 1);
- $inf->{admin}->{ServerAdminID} = $rdns[0];
+ $inf->{admin}->{ServerAdminID} = $query->param('suitespot3x_uid');
+ if (!$inf->{admin}->{ServerAdminID}) {
+ # Still can not find the admin user, we must use the logged in user
+ my @rdns = ldap_explode_dn($inf->{General}->{ConfigDirectoryAdminID}, 1);
+ $inf->{admin}->{ServerAdminID} = $rdns[0];
+ }
}
if (!createSubDSNoConn($inf, \@errs)) {
9 years, 8 months
Branch '389-ds-base-1.2.11' - ldap/servers
by Noriko Hosoi
ldap/servers/slapd/back-ldbm/idl_common.c | 17 ++++++++++++++++-
1 file changed, 16 insertions(+), 1 deletion(-)
New commits:
commit 488fa1229f0f0b80cbe43f2e52c2e2b3aaefe188
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Thu Aug 21 13:01:30 2014 -0700
Bug 1129660 - Adding users to user group throws Internal server error.
Description: 389-ds-base-1.2.11 branch did not have the commit
a71633d56951dd6c4d0368c790b85628f1598968 (Ticket #47313 - Indexed
search with filter containing '&' and "!" with attribute subtypes
gives wrong result).
This patch backporting just the NULL idl checking in idl_common.c
from the commit to the 389-ds-base-1.2.11 branch.
https://bugzilla.redhat.com/show_bug.cgi?id=1129660
Reviewed by nkinder(a)redhat.com (Thank you, Nathan!!)
diff --git a/ldap/servers/slapd/back-ldbm/idl_common.c b/ldap/servers/slapd/back-ldbm/idl_common.c
index 216bfb0..efac186 100644
--- a/ldap/servers/slapd/back-ldbm/idl_common.c
+++ b/ldap/servers/slapd/back-ldbm/idl_common.c
@@ -46,16 +46,25 @@
size_t idl_sizeof(IDList *idl)
{
+ if (NULL == idl) {
+ return 0;
+ }
return (2 + idl->b_nmax) * sizeof(ID);
}
NIDS idl_length(IDList *idl)
{
+ if (NULL == idl) {
+ return 0;
+ }
return (idl->b_nmax == ALLIDSBLOCK) ? UINT_MAX : idl->b_nids;
}
int idl_is_allids(IDList *idl)
{
+ if (NULL == idl) {
+ return 0;
+ }
return (idl->b_nmax == ALLIDSBLOCK);
}
@@ -110,6 +119,9 @@ idl_free( IDList **idl )
int
idl_append( IDList *idl, ID id)
{
+ if (NULL == idl) {
+ return 2;
+ }
if ( ALLIDS( idl ) || ( (idl->b_nids) && (idl->b_ids[idl->b_nids - 1] == id)) ) {
return( 1 ); /* already there */
}
@@ -321,7 +333,7 @@ idl_notin(
backend *be,
IDList *a,
IDList *b,
- IDList **new_result
+ IDList **new_result
)
{
NIDS ni, ai, bi;
@@ -435,6 +447,9 @@ idl_nextid( IDList *idl, ID id )
{
NIDS i;
+ if (NULL == idl) {
+ return NOID;
+ }
if ( ALLIDS( idl ) ) {
return( ++id < idl->b_nids ? id : NOID );
}
9 years, 8 months
Branch '389-ds-base-1.2.11' - Makefile.in configure
by Noriko Hosoi
Makefile.in | 2 -
configure | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
2 files changed, 81 insertions(+), 8 deletions(-)
New commits:
commit 4a16332967096c6872ecf7e3686da3f7360b9b5f
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Wed Aug 20 18:20:41 2014 -0400
Ticket #47875 - dirsrv not running with old openldap
Description: Automatically generated files by autogen.sh.
diff --git a/Makefile.in b/Makefile.in
index f731cfb..930d22b 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -10428,7 +10428,7 @@ distcheck: dist
*.zip*) \
unzip $(distdir).zip ;;\
esac
- chmod -R a-w $(distdir); chmod a+w $(distdir)
+ chmod -R a-w $(distdir); chmod u+w $(distdir)
mkdir $(distdir)/_build
mkdir $(distdir)/_inst
chmod a-w $(distdir)
diff --git a/configure b/configure
index fba5e4f..8f2cfcc 100755
--- a/configure
+++ b/configure
@@ -22505,14 +22505,14 @@ fi
ldap_lib_ldif=""
LDFLAGS="$LDFLAGS"
- as_ac_Lib=`$as_echo "ac_cv_lib_ldap$ol_libver''_ldif_open" | $as_tr_sh`
-{ $as_echo "$as_me:$LINENO: checking for ldif_open in -lldap$ol_libver" >&5
-$as_echo_n "checking for ldif_open in -lldap$ol_libver... " >&6; }
+ as_ac_Lib=`$as_echo "ac_cv_lib_ldif$ol_libver''__init" | $as_tr_sh`
+{ $as_echo "$as_me:$LINENO: checking for _init in -lldif$ol_libver" >&5
+$as_echo_n "checking for _init in -lldif$ol_libver... " >&6; }
if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then
$as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
-LIBS="-lldap$ol_libver $LIBS"
+LIBS="-lldif$ol_libver $LIBS"
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
@@ -22526,11 +22526,11 @@ cat >>conftest.$ac_ext <<_ACEOF
#ifdef __cplusplus
extern "C"
#endif
-char ldif_open ();
+char _init ();
int
main ()
{
-return ldif_open ();
+return _init ();
;
return 0;
}
@@ -22576,11 +22576,84 @@ $as_echo "$ac_res" >&6; }
as_val=`eval 'as_val=${'$as_ac_Lib'}
$as_echo "$as_val"'`
if test "x$as_val" = x""yes; then
+ ldap_lib_ldif=-lldif$ol_libver
+else
ldap_lib_ldif=
+fi
+
+ if test -z "$ldap_lib_ldif" ; then
+ { $as_echo "$as_me:$LINENO: checking for _init in -lldif" >&5
+$as_echo_n "checking for _init in -lldif... " >&6; }
+if test "${ac_cv_lib_ldif__init+set}" = set; then
+ $as_echo_n "(cached) " >&6
else
- ldap_lib_ldif=-lldif$ol_libver
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lldif $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char _init ();
+int
+main ()
+{
+return _init ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ $as_test_x conftest$ac_exeext
+ }; then
+ ac_cv_lib_ldif__init=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_lib_ldif__init=no
fi
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_ldif__init" >&5
+$as_echo "$ac_cv_lib_ldif__init" >&6; }
+if test "x$ac_cv_lib_ldif__init" = x""yes; then
+ ldap_lib_ldif=-lldif
+else
+ ldap_lib_ldif=
+fi
+
+ fi
LDFLAGS="$save_ldflags"
CPPFLAGS="$save_cppflags"
9 years, 8 months
Branch '389-ds-base-1.2.11' - 3 commits - Makefile.in configure configure.ac m4/openldap.m4
by Noriko Hosoi
Makefile.in | 2 +-
configure | 1 -
configure.ac | 1 -
m4/openldap.m4 | 8 ++++++--
4 files changed, 7 insertions(+), 5 deletions(-)
New commits:
commit 62ef849326a010e9a17c576817b0afc2830a8a6d
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Wed Aug 20 13:51:40 2014 -0700
Ticket #47875 - dirsrv not running with old openldap
Description: Changing the function of AC_CHECK_LIB from ldif_open
to _init so that regardless of the contents of the library, it's
linked to the server if it exists.
https://fedorahosted.org/389/ticket/47875
Reviewed by rmeggins(a)redhat.com (Thank you, Rich!!)
(cherry picked from commit 38c74d224c250abd907636f7d78e95775ebf63dd)
(cherry picked from commit 4917a5e4856c7fe0fb4f9b023c21eb64f277e319)
diff --git a/m4/openldap.m4 b/m4/openldap.m4
index 74700d7..1e297c4 100644
--- a/m4/openldap.m4
+++ b/m4/openldap.m4
@@ -146,8 +146,12 @@ if test "$with_openldap" = yes ; then
dnl ldif functionality into libldap
ldap_lib_ldif=""
LDFLAGS="$LDFLAGS"
- AC_CHECK_LIB([ldap$ol_libver], [ldif_open], [ldap_lib_ldif=],
- [ldap_lib_ldif=-lldif$ol_libver])
+ AC_CHECK_LIB([ldif$ol_libver], [_init], [ldap_lib_ldif=-lldif$ol_libver],
+ [ldap_lib_ldif=])
+ if test -z "$ldap_lib_ldif" ; then
+ AC_CHECK_LIB([ldif], [_init], [ldap_lib_ldif=-lldif],
+ [ldap_lib_ldif=])
+ fi
AC_SUBST([ldap_lib_ldif])
LDFLAGS="$save_ldflags"
CPPFLAGS="$save_cppflags"
commit f98bdeea02328bcd1746d909c4d51bc6bfa27fb8
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Wed Aug 20 15:17:36 2014 -0700
Revert "Ticket #47875 - dirsrv not running with old openldap"
This reverts commit dce84e1d4a12dbe9a461981d076ca3d0e17ef56c.
diff --git a/configure.ac b/configure.ac
index fd2e0d2..8281d67 100644
--- a/configure.ac
+++ b/configure.ac
@@ -655,7 +655,6 @@ AC_SUBST(openldap_inc)
AC_SUBST(openldap_lib)
AC_SUBST(openldap_libdir)
AC_SUBST(openldap_bindir)
-AC_SUBST(ldap_lib_ldif)
AC_SUBST(ldaptool_bindir)
AC_SUBST(ldaptool_opts)
AC_SUBST(plainldif_opts)
commit 576af11ec0f474b631b1580a393068eb780ce3c2
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Wed Aug 20 15:17:24 2014 -0700
Revert "Ticket #47875 - dirsrv not running with old openldap"
This reverts commit e476c664d6ad2875e454722c6451a5411b1f38d1.
diff --git a/Makefile.in b/Makefile.in
index 930d22b..f731cfb 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -10428,7 +10428,7 @@ distcheck: dist
*.zip*) \
unzip $(distdir).zip ;;\
esac
- chmod -R a-w $(distdir); chmod u+w $(distdir)
+ chmod -R a-w $(distdir); chmod a+w $(distdir)
mkdir $(distdir)/_build
mkdir $(distdir)/_inst
chmod a-w $(distdir)
diff --git a/configure b/configure
index c22046c..fba5e4f 100755
--- a/configure
+++ b/configure
@@ -25155,7 +25155,6 @@ fi
-
cat >>confdefs.h <<\_ACEOF
#define LDAP_DEBUG 1
_ACEOF
9 years, 8 months
Branch '389-ds-base-1.3.2' - 4 commits - configure configure.ac m4/openldap.m4
by Noriko Hosoi
configure | 59 +++++++++++++++++++++++++++++++++++++++++++++++++--------
configure.ac | 1
m4/openldap.m4 | 8 +++++--
3 files changed, 57 insertions(+), 11 deletions(-)
New commits:
commit 939838311c6366b1cf4ba04a9f0a1b2b6adfb34d
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Wed Aug 20 15:15:12 2014 -0700
Ticket #47875 - dirsrv not running with old openldap
Description: Automatically generated files by autogen.sh.
diff --git a/configure b/configure
index fd1bfb6..c450b65 100755
--- a/configure
+++ b/configure
@@ -19288,14 +19288,14 @@ fi
ldap_lib_ldif=""
LDFLAGS="$LDFLAGS"
- as_ac_Lib=`$as_echo "ac_cv_lib_ldap$ol_libver''_ldif_open" | $as_tr_sh`
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ldif_open in -lldap$ol_libver" >&5
-$as_echo_n "checking for ldif_open in -lldap$ol_libver... " >&6; }
+ as_ac_Lib=`$as_echo "ac_cv_lib_ldif$ol_libver''__init" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for _init in -lldif$ol_libver" >&5
+$as_echo_n "checking for _init in -lldif$ol_libver... " >&6; }
if eval \${$as_ac_Lib+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
-LIBS="-lldap$ol_libver $LIBS"
+LIBS="-lldif$ol_libver $LIBS"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
@@ -19305,11 +19305,11 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
#ifdef __cplusplus
extern "C"
#endif
-char ldif_open ();
+char _init ();
int
main ()
{
-return ldif_open ();
+return _init ();
;
return 0;
}
@@ -19327,11 +19327,55 @@ eval ac_res=\$$as_ac_Lib
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
$as_echo "$ac_res" >&6; }
if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+ ldap_lib_ldif=-lldif$ol_libver
+else
ldap_lib_ldif=
+fi
+
+ if test -z "$ldap_lib_ldif" ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _init in -lldif" >&5
+$as_echo_n "checking for _init in -lldif... " >&6; }
+if ${ac_cv_lib_ldif__init+:} false; then :
+ $as_echo_n "(cached) " >&6
else
- ldap_lib_ldif=-lldif$ol_libver
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lldif $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char _init ();
+int
+main ()
+{
+return _init ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_ldif__init=yes
+else
+ ac_cv_lib_ldif__init=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ldif__init" >&5
+$as_echo "$ac_cv_lib_ldif__init" >&6; }
+if test "x$ac_cv_lib_ldif__init" = xyes; then :
+ ldap_lib_ldif=-lldif
+else
+ ldap_lib_ldif=
fi
+ fi
LDFLAGS="$save_ldflags"
CPPFLAGS="$save_cppflags"
commit 4917a5e4856c7fe0fb4f9b023c21eb64f277e319
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Wed Aug 20 13:51:40 2014 -0700
Ticket #47875 - dirsrv not running with old openldap
Description: Changing the function of AC_CHECK_LIB from ldif_open
to _init so that regardless of the contents of the library, it's
linked to the server if it exists.
https://fedorahosted.org/389/ticket/47875
Reviewed by rmeggins(a)redhat.com (Thank you, Rich!!)
(cherry picked from commit 38c74d224c250abd907636f7d78e95775ebf63dd)
diff --git a/m4/openldap.m4 b/m4/openldap.m4
index 74700d7..1e297c4 100644
--- a/m4/openldap.m4
+++ b/m4/openldap.m4
@@ -146,8 +146,12 @@ if test "$with_openldap" = yes ; then
dnl ldif functionality into libldap
ldap_lib_ldif=""
LDFLAGS="$LDFLAGS"
- AC_CHECK_LIB([ldap$ol_libver], [ldif_open], [ldap_lib_ldif=],
- [ldap_lib_ldif=-lldif$ol_libver])
+ AC_CHECK_LIB([ldif$ol_libver], [_init], [ldap_lib_ldif=-lldif$ol_libver],
+ [ldap_lib_ldif=])
+ if test -z "$ldap_lib_ldif" ; then
+ AC_CHECK_LIB([ldif], [_init], [ldap_lib_ldif=-lldif],
+ [ldap_lib_ldif=])
+ fi
AC_SUBST([ldap_lib_ldif])
LDFLAGS="$save_ldflags"
CPPFLAGS="$save_cppflags"
commit 977b77574e47b1b1962482e292d3f5b3a24d3f35
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Wed Aug 20 15:14:08 2014 -0700
Revert "Ticket #47875 - dirsrv not running with old openldap"
This reverts commit 1bb438916825d72df023ca5f67fa7d8b7e6e36e3.
diff --git a/configure.ac b/configure.ac
index e7f412d..908683e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -664,7 +664,6 @@ AC_SUBST(openldap_inc)
AC_SUBST(openldap_lib)
AC_SUBST(openldap_libdir)
AC_SUBST(openldap_bindir)
-AC_SUBST(ldap_lib_ldif)
AC_SUBST(ldaptool_bindir)
AC_SUBST(ldaptool_opts)
AC_SUBST(plainldif_opts)
commit ec85360af0b930b6abaee27938c217a857a91504
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Wed Aug 20 15:13:54 2014 -0700
Revert "Ticket #47875 - dirsrv not running with old openldap"
This reverts commit 5995ff014d92da027f4ee925aefc6d7249a169bc.
diff --git a/configure b/configure
index 408275c..fd1bfb6 100755
--- a/configure
+++ b/configure
@@ -21212,7 +21212,6 @@ fi
-
# AC_DEFINE([USE_OLD_UNHASHED], [], [Use old unhashed code])
$as_echo "#define LDAP_DEBUG 1" >>confdefs.h
9 years, 8 months
configure.ac
by Noriko Hosoi
configure.ac | 1 -
1 file changed, 1 deletion(-)
New commits:
commit cb7ccc2d610880e21e5cd1fae1c40db96e9bc278
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Wed Aug 20 15:09:57 2014 -0700
Revert "Ticket #47875 - dirsrv not running with old openldap"
This reverts commit 0ae55bcd61497c2fa7aaade40fe4ff6c91216325.
diff --git a/configure.ac b/configure.ac
index 0f1ddf6..16ab6a9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -709,7 +709,6 @@ AC_SUBST(openldap_inc)
AC_SUBST(openldap_lib)
AC_SUBST(openldap_libdir)
AC_SUBST(openldap_bindir)
-AC_SUBST(ldap_lib_ldif)
AC_SUBST(ldaptool_bindir)
AC_SUBST(ldaptool_opts)
AC_SUBST(plainldif_opts)
9 years, 8 months
2 commits - configure m4/openldap.m4
by Noriko Hosoi
configure | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++-------
m4/openldap.m4 | 8 +++++--
2 files changed, 57 insertions(+), 9 deletions(-)
New commits:
commit a595bd8649ac25ab5657e1176c782090aae9c2a8
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Wed Aug 20 14:07:01 2014 -0700
Ticket #47875 - dirsrv not running with old openldap
Description: Automatically generated files by autogen.sh.
diff --git a/configure b/configure
index 158db9a..ec58a1b 100755
--- a/configure
+++ b/configure
@@ -19408,14 +19408,14 @@ fi
ldap_lib_ldif=""
LDFLAGS="$LDFLAGS"
- as_ac_Lib=`$as_echo "ac_cv_lib_ldap$ol_libver''_ldif_open" | $as_tr_sh`
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ldif_open in -lldap$ol_libver" >&5
-$as_echo_n "checking for ldif_open in -lldap$ol_libver... " >&6; }
+ as_ac_Lib=`$as_echo "ac_cv_lib_ldif$ol_libver''__init" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for _init in -lldif$ol_libver" >&5
+$as_echo_n "checking for _init in -lldif$ol_libver... " >&6; }
if eval \${$as_ac_Lib+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
-LIBS="-lldap$ol_libver $LIBS"
+LIBS="-lldif$ol_libver $LIBS"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
@@ -19425,11 +19425,11 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
#ifdef __cplusplus
extern "C"
#endif
-char ldif_open ();
+char _init ();
int
main ()
{
-return ldif_open ();
+return _init ();
;
return 0;
}
@@ -19447,11 +19447,55 @@ eval ac_res=\$$as_ac_Lib
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
$as_echo "$ac_res" >&6; }
if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+ ldap_lib_ldif=-lldif$ol_libver
+else
ldap_lib_ldif=
+fi
+
+ if test -z "$ldap_lib_ldif" ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _init in -lldif" >&5
+$as_echo_n "checking for _init in -lldif... " >&6; }
+if ${ac_cv_lib_ldif__init+:} false; then :
+ $as_echo_n "(cached) " >&6
else
- ldap_lib_ldif=-lldif$ol_libver
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lldif $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char _init ();
+int
+main ()
+{
+return _init ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_ldif__init=yes
+else
+ ac_cv_lib_ldif__init=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ldif__init" >&5
+$as_echo "$ac_cv_lib_ldif__init" >&6; }
+if test "x$ac_cv_lib_ldif__init" = xyes; then :
+ ldap_lib_ldif=-lldif
+else
+ ldap_lib_ldif=
fi
+ fi
LDFLAGS="$save_ldflags"
CPPFLAGS="$save_cppflags"
commit 38c74d224c250abd907636f7d78e95775ebf63dd
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Wed Aug 20 13:51:40 2014 -0700
Ticket #47875 - dirsrv not running with old openldap
Description: Changing the function of AC_CHECK_LIB from ldif_open
to _init so that regardless of the contents of the library, it's
linked to the server if it exists.
https://fedorahosted.org/389/ticket/47875
Reviewed by rmeggins(a)redhat.com (Thank you, Rich!!)
diff --git a/m4/openldap.m4 b/m4/openldap.m4
index 74700d7..1e297c4 100644
--- a/m4/openldap.m4
+++ b/m4/openldap.m4
@@ -146,8 +146,12 @@ if test "$with_openldap" = yes ; then
dnl ldif functionality into libldap
ldap_lib_ldif=""
LDFLAGS="$LDFLAGS"
- AC_CHECK_LIB([ldap$ol_libver], [ldif_open], [ldap_lib_ldif=],
- [ldap_lib_ldif=-lldif$ol_libver])
+ AC_CHECK_LIB([ldif$ol_libver], [_init], [ldap_lib_ldif=-lldif$ol_libver],
+ [ldap_lib_ldif=])
+ if test -z "$ldap_lib_ldif" ; then
+ AC_CHECK_LIB([ldif], [_init], [ldap_lib_ldif=-lldif],
+ [ldap_lib_ldif=])
+ fi
AC_SUBST([ldap_lib_ldif])
LDFLAGS="$save_ldflags"
CPPFLAGS="$save_cppflags"
9 years, 8 months