ldap/servers/plugins/replication/repl5_replica_config.c | 3
ldap/servers/slapd/back-ldbm/dblayer.c | 41 ++
ldap/servers/slapd/back-ldbm/ldbm_delete.c | 25 +
ldap/servers/slapd/back-ldbm/ldbm_modify.c | 278 +++++++++-------
4 files changed, 231 insertions(+), 116 deletions(-)
New commits:
commit 8e67aac72ce0802bd9dc7285da340191b71dafc3
Author: Rich Megginson <rmeggins(a)redhat.com>
Date: Mon Jun 18 12:21:50 2012 -0600
Ticket #387 - managed entry sometimes doesn't delete the managed entry
https://fedorahosted.org/389/ticket/387
Resolves: Ticket #387
Bug Description: managed entry sometimes doesn't delete the managed entry
Reviewed by: ???
Branch: master
Fix Description: A modify just replaces the old entry in the cache with
the new entry, and the modify code only does the cache_replace if the
database operations succeed, so we don't have to do any cache cleanup
in the txn retry loop. Also cleanup some other cache usage. If there
is an error and ec is in the cache, we still have to remove it and restore
the original e entry.
Platforms tested: RHEL6 x86_64, Fedora 17
Flag Day: no
Doc impact: no
(cherry picked from commit 65ec7c2f1f3989fe0ea7876909a9f882ecb2a1ec)
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modify.c
b/ldap/servers/slapd/back-ldbm/ldbm_modify.c
index 8bd75b2..6d2e6f6 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_modify.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_modify.c
@@ -187,6 +187,122 @@ error:
return retval;
}
+/**
+ Apply the mods to the ec entry. Check for syntax, schema problems.
+ Check for abandon.
+
+ Return code:
+ -1 - error - result code and message are set appropriately
+ 0 - successfully applied and checked
+ 1 - not an error - no mods to apply or op abandoned
+ */
+static int
+modify_apply_check_expand(
+ Slapi_PBlock *pb,
+ Slapi_Operation *operation,
+ LDAPMod **mods, /* list of mods to apply */
+ struct backentry *e, /* original "before" entry */
+ struct backentry *ec, /* "after" entry with mods applied */
+ Slapi_Entry **postentry,
+ int *ldap_result_code,
+ char **ldap_result_message
+)
+{
+ int rc = 0;
+ int i;
+ int repl_op;
+ int change_entry = 0;
+ Slapi_Mods smods = {0};
+ CSN *csn = operation_get_csn(operation);
+
+ slapi_pblock_get (pb, SLAPI_IS_REPLICATED_OPERATION, &repl_op);
+ slapi_mods_init_byref( &smods, mods );
+
+ if ( (change_entry = mods_have_effect (ec->ep_entry, &smods)) ) {
+ *ldap_result_code = entry_apply_mods_wsi(ec->ep_entry, &smods, csn,
+ operation_is_flag_set(operation, OP_FLAG_REPLICATED));
+ /*
+ * XXXmcs: it would be nice to get back an error message from
+ * the above call so we could pass it along to the client, e.g.,
+ * "duplicate value for attribute givenName."
+ */
+ } else {
+ Slapi_Entry *epostop = NULL;
+ /* If the entry was not actually changed, we still need to
+ * set the SLAPI_ENTRY_POST_OP field in the pblock (post-op
+ * plugins expect that field to be present for all modify
+ * operations that return LDAP_SUCCESS).
+ */
+ slapi_pblock_get ( pb, SLAPI_ENTRY_POST_OP, &epostop );
+ slapi_entry_free ( epostop ); /* free existing one, if any */
+ slapi_pblock_set ( pb, SLAPI_ENTRY_POST_OP, slapi_entry_dup( e->ep_entry ) );
+ *postentry = NULL; /* to avoid free in main error cleanup code */
+ }
+ if ( !change_entry || *ldap_result_code != 0 ) {
+ /* change_entry == 0 is not an error just a no-op */
+ rc = change_entry ? -1 : 1;
+ goto done;
+ }
+
+ /*
+ * If the objectClass attribute type was modified in any way, expand
+ * the objectClass values to reflect the inheritance hierarchy.
+ */
+ for ( i = 0; mods[i] != NULL && !repl_op; ++i ) {
+ if ( 0 == strcasecmp( SLAPI_ATTR_OBJECTCLASS, mods[i]->mod_type )) {
+ slapi_schema_expand_objectclasses( ec->ep_entry );
+ break;
+ }
+ }
+
+ /*
+ * We are about to pass the last abandon test, so from now on we are
+ * committed to finish this operation. Set status to "will complete"
+ * before we make our last abandon check to avoid race conditions in
+ * the code that processes abandon operations.
+ */
+ operation->o_status = SLAPI_OP_STATUS_WILL_COMPLETE;
+ if ( slapi_op_abandoned( pb ) ) {
+ rc = 1;
+ goto done;
+ }
+
+ /* if this is a replicated op, we don't need to perform these checks */
+ if(!repl_op){
+ /* check that the entry still obeys the schema */
+ if ((operation_is_flag_set(operation,OP_FLAG_ACTION_SCHEMA_CHECK)) &&
+ slapi_entry_schema_check( pb, ec->ep_entry ) != 0 ) {
+ *ldap_result_code = LDAP_OBJECT_CLASS_VIOLATION;
+ slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, ldap_result_message);
+ rc = -1;
+ goto done;
+ }
+
+ /* check attribute syntax for the new values */
+ if (slapi_mods_syntax_check(pb, mods, 0) != 0) {
+ *ldap_result_code = LDAP_INVALID_SYNTAX;
+ slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, ldap_result_message);
+ rc = -1;
+ goto done;
+ }
+
+ /*
+ * make sure the entry contains all values in the RDN.
+ * if not, the modification must have removed them.
+ */
+ if ( ! slapi_entry_rdn_values_present( ec->ep_entry ) ) {
+ *ldap_result_code= LDAP_NOT_ALLOWED_ON_RDN;
+ rc = -1;
+ goto done;
+ }
+ }
+
+done:
+ slapi_mods_done( &smods );
+
+ return rc;
+}
+
int
ldbm_back_modify( Slapi_PBlock *pb )
{
@@ -213,14 +329,13 @@ ldbm_back_modify( Slapi_PBlock *pb )
Slapi_Operation *operation;
int dblock_acquired= 0;
entry_address *addr;
- int change_entry = 0;
int ec_in_cache = 0;
int is_fixup_operation= 0;
int is_ruv = 0; /* True if the current entry is RUV */
CSN *opcsn = NULL;
int repl_op;
- int i = 0;
int opreturn = 0;
+ int mod_count = 0;
slapi_pblock_get( pb, SLAPI_BACKEND, &be);
slapi_pblock_get( pb, SLAPI_PLUGIN_PRIVATE, &li );
@@ -342,82 +457,14 @@ ldbm_back_modify( Slapi_PBlock *pb )
/* The Plugin may have messed about with some of the PBlock parameters... ie. mods */
slapi_pblock_get( pb, SLAPI_MODIFY_MODS, &mods );
slapi_mods_init_byref(&smods,mods);
+ mod_count = slapi_mods_get_num_mods(&smods);
- {
- CSN *csn = operation_get_csn(operation);
- if ( (change_entry = mods_have_effect (ec->ep_entry, &smods)) ) {
- ldap_result_code = entry_apply_mods_wsi(ec->ep_entry, &smods, csn,
operation_is_flag_set(operation,OP_FLAG_REPLICATED));
- /*
- * XXXmcs: it would be nice to get back an error message from
- * the above call so we could pass it along to the client, e.g.,
- * "duplicate value for attribute givenName."
- */
- } else {
- /* If the entry was not actually changed, we still need to
- * set the SLAPI_ENTRY_POST_OP field in the pblock (post-op
- * plugins expect that field to be present for all modify
- * operations that return LDAP_SUCCESS).
- */
- postentry = slapi_entry_dup( e->ep_entry );
- slapi_pblock_set ( pb, SLAPI_ENTRY_POST_OP, postentry );
- postentry = NULL; /* avoid removal/free in error_return code */
- }
- if ( !change_entry || ldap_result_code != 0 ) {
- /* change_entry == 0 is not an error, but we need to free lock etc */
- goto error_return;
- }
- }
-
- /*
- * If the objectClass attribute type was modified in any way, expand
- * the objectClass values to reflect the inheritance hierarchy.
- */
- for ( i = 0; mods[i] != NULL && !repl_op; ++i ) {
- if ( 0 == strcasecmp( SLAPI_ATTR_OBJECTCLASS, mods[i]->mod_type )) {
- slapi_schema_expand_objectclasses( ec->ep_entry );
- break;
- }
- }
-
- /*
- * We are about to pass the last abandon test, so from now on we are
- * committed to finish this operation. Set status to "will complete"
- * before we make our last abandon check to avoid race conditions in
- * the code that processes abandon operations.
- */
- operation->o_status = SLAPI_OP_STATUS_WILL_COMPLETE;
- if ( slapi_op_abandoned( pb ) ) {
+ /* apply the mods, check for syntax, schema problems, etc. */
+ if (modify_apply_check_expand(pb, operation, mods, e, ec, &postentry,
+ &ldap_result_code, &ldap_result_message)) {
goto error_return;
}
- /* if this is a replicated op, we don't need to perform these checks */
- if(!repl_op){
- /* check that the entry still obeys the schema */
- if ((operation_is_flag_set(operation,OP_FLAG_ACTION_SCHEMA_CHECK)) &&
- slapi_entry_schema_check( pb, ec->ep_entry ) != 0 ) {
- ldap_result_code= LDAP_OBJECT_CLASS_VIOLATION;
- slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, &ldap_result_message);
- goto error_return;
- }
-
- /* check attribute syntax for the new values */
- if (slapi_mods_syntax_check(pb, mods, 0) != 0)
- {
- ldap_result_code = LDAP_INVALID_SYNTAX;
- slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, &ldap_result_message);
- goto error_return;
- }
-
- /*
- * make sure the entry contains all values in the RDN.
- * if not, the modification must have removed them.
- */
- if ( ! slapi_entry_rdn_values_present( ec->ep_entry ) ) {
- ldap_result_code= LDAP_NOT_ALLOWED_ON_RDN;
- goto error_return;
- }
- }
-
if (!is_ruv && !is_fixup_operation) {
ruv_c_init = ldbm_txn_ruv_modify_context( pb, &ruv_c );
if (-1 == ruv_c_init) {
@@ -437,7 +484,7 @@ ldbm_back_modify( Slapi_PBlock *pb )
* their original state;
*/
mods_original = copy_mods(mods);
- if ( (original_entry = backentry_dup( e )) == NULL ) {
+ if ( (original_entry = backentry_dup( ec )) == NULL ) {
ldap_result_code= LDAP_OPERATIONS_ERROR;
goto error_return;
}
@@ -445,6 +492,7 @@ ldbm_back_modify( Slapi_PBlock *pb )
txn.back_txn_txn = NULL; /* ready to create the child transaction */
for (retry_count = 0; retry_count < RETRY_TIMES; retry_count++) {
int cache_rc = 0;
+ int new_mod_count = 0;
if (txn.back_txn_txn && (txn.back_txn_txn != parent_txn)) {
dblayer_txn_abort(li,&txn);
slapi_pblock_set(pb, SLAPI_TXN, parent_txn);
@@ -453,6 +501,7 @@ ldbm_back_modify( Slapi_PBlock *pb )
* We need to grab the current mods, free them, and restore the
* originals. Same thing for the entry.
*/
+
slapi_pblock_get(pb, SLAPI_MODIFY_MODS, &mods);
ldap_mods_free(mods, 1);
slapi_pblock_set(pb, SLAPI_MODIFY_MODS, copy_mods(mods_original));
@@ -461,10 +510,11 @@ ldbm_back_modify( Slapi_PBlock *pb )
backentry_free(&ec);
slapi_pblock_set( pb, SLAPI_MODIFY_EXISTING_ENTRY, original_entry->ep_entry );
ec = original_entry;
- if ( (original_entry = backentry_dup( e )) == NULL ) {
+ if ( (original_entry = backentry_dup( ec )) == NULL ) {
ldap_result_code= LDAP_OPERATIONS_ERROR;
goto error_return;
}
+
LDAPDebug0Args(LDAP_DEBUG_BACKLDBM,
"Modify Retrying Transaction\n");
#ifndef LDBM_NO_BACKOFF_DELAY
@@ -503,6 +553,25 @@ ldbm_back_modify( Slapi_PBlock *pb )
/* the mods might have been changed, so get the latest */
slapi_pblock_get( pb, SLAPI_MODIFY_MODS, &mods );
+ /* make sure the betxnpreop did not alter any of the mods that
+ had already previously been applied */
+ slapi_mods_done(&smods);
+ slapi_mods_init_byref(&smods,mods);
+ new_mod_count = slapi_mods_get_num_mods(&smods);
+ if (new_mod_count < mod_count) {
+ LDAPDebug2Args( LDAP_DEBUG_ANY, "Error: BE_TXN_PRE_MODIFY plugin has removed
"
+ "mods from the original list - mod count was [%d] now [%d] "
+ "mods will not be applied - mods list changes must be done "
+ "in the BE_PRE_MODIFY plugin, not the BE_TXN_PRE_MODIFY\n",
+ mod_count, new_mod_count );
+ } else if (new_mod_count > mod_count) { /* apply the new betxnpremod mods */
+ /* apply the mods, check for syntax, schema problems, etc. */
+ if (modify_apply_check_expand(pb, operation, &mods[mod_count], e, ec,
&postentry,
+ &ldap_result_code, &ldap_result_message)) {
+ goto error_return;
+ }
+ } /* else if new_mod_count == mod_count then betxnpremod plugin did nothing */
+
/*
* Update the ID to Entry index.
* Note that id2entry_add replaces the entry, so the Entry ID
commit f2818827cf38046a16f9b7f39779ae5ab53338bd
Author: Rich Megginson <rmeggins(a)redhat.com>
Date: Wed Jun 13 21:03:37 2012 -0600
Ticket #387 - managed entry sometimes doesn't delete the managed entry
https://fedorahosted.org/389/ticket/387
Resolves: Ticket #387
Bug Description: managed entry sometimes doesn't delete the managed entry
Reviewed by: ???
Branch: master
Fix Description: A modify just replaces the old entry in the cache with
the new entry, and the modify code only does the cache_replace if the
database operations succeed, so we don't have to do any cache cleanup
in the txn retry loop. Also cleanup some other cache usage.
Platforms tested: RHEL6 x86_64, Fedora 17
Flag Day: no
Doc impact: no
(cherry picked from commit 2e9756be7d0e755ede0ff04f273311d98fa03aff)
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modify.c
b/ldap/servers/slapd/back-ldbm/ldbm_modify.c
index f7520c6..8bd75b2 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_modify.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_modify.c
@@ -456,15 +456,9 @@ 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));
- if (ec_in_cache) {
- /* New entry 'ec' is in the entry cache.
- * Remove it from the cache once. */
- CACHE_REMOVE(&inst->inst_cache, ec);
- CACHE_RETURN(&inst->inst_cache, &ec);
- } else {
- backentry_free(&ec);
- }
- ec_in_cache = 0; /* added to cache by id2entry - have to remove to try again */
+ /* 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( e )) == NULL ) {
@@ -527,14 +521,6 @@ ldbm_back_modify( Slapi_PBlock *pb )
MOD_SET_ERROR(ldap_result_code, LDAP_OPERATIONS_ERROR, retry_count);
goto error_return;
}
- /*
- * id2entry_add tries to put ec into the entry cache,
- * but due to the conflict with original 'e',
- * the cache_add (called vai id2entry_add) could fail.
- */
- if (0 == cache_rc) {
- ec_in_cache = 1;
- }
retval = index_add_mods( be, mods, e, ec, &txn );
if (DB_LOCK_DEADLOCK == retval)
{
@@ -612,6 +598,8 @@ ldbm_back_modify( Slapi_PBlock *pb )
MOD_SET_ERROR(ldap_result_code, LDAP_OPERATIONS_ERROR, retry_count);
goto error_return;
}
+ /* 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 );
@@ -663,26 +651,12 @@ ldbm_back_modify( Slapi_PBlock *pb )
goto common_return;
error_return:
- if (ec_in_cache)
- {
- CACHE_REMOVE( &inst->inst_cache, ec );
- }
- else
- {
- backentry_free(&ec);
- }
if ( postentry != NULL )
{
slapi_entry_free( postentry );
postentry = NULL;
slapi_pblock_set( pb, SLAPI_ENTRY_POST_OP, NULL );
}
-
- if (e!=NULL) {
- cache_unlock_entry( &inst->inst_cache, e);
- CACHE_RETURN( &inst->inst_cache, &e);
- }
-
if (retval == DB_RUNRECOVERY) {
dblayer_remember_disk_filled(li);
ldbm_nasty("Modify",81,retval);
@@ -730,14 +704,33 @@ error_return:
rc= SLAPI_FAIL_GENERAL;
}
-
+ /* if ec is in cache, remove it, then add back e if we still have it */
+ if (ec_in_cache) {
+ CACHE_REMOVE( &inst->inst_cache, ec );
+ /* if ec was in cache, e was not - add back e */
+ if (e) {
+ CACHE_ADD( &inst->inst_cache, e, NULL );
+ cache_lock_entry( &inst->inst_cache, e );
+ }
+ }
+
common_return:
slapi_mods_done(&smods);
if (ec_in_cache)
{
+ cache_unlock_entry( &inst->inst_cache, ec);
CACHE_RETURN( &inst->inst_cache, &ec );
}
+ else
+ {
+ backentry_free(&ec);
+ }
+
+ if (e!=NULL) {
+ cache_unlock_entry( &inst->inst_cache, e);
+ CACHE_RETURN( &inst->inst_cache, &e);
+ }
/* result code could be used in the bepost plugin functions. */
slapi_pblock_set(pb, SLAPI_RESULT_CODE, &ldap_result_code);
commit 59038150a3f351613fcafb19f7d9c8eb2240cdce
Author: Rich Megginson <rmeggins(a)redhat.com>
Date: Fri Jun 15 16:18:33 2012 -0600
improve txn test index handling
Sometimes it is difficult to determine which indexes actually have files,
and the txn thread would keep looping forever looking for missing files.
This changes the txn thread to retry a few times, then just start skipping
missing indexes. The txn thread will log which indexes it uses and which
it skipped.
(cherry picked from 36180b1754e9907a189afff4ed7683ce5ca6b48b)
diff --git a/ldap/servers/slapd/back-ldbm/dblayer.c
b/ldap/servers/slapd/back-ldbm/dblayer.c
index 90e48af..ed90e2d 100644
--- a/ldap/servers/slapd/back-ldbm/dblayer.c
+++ b/ldap/servers/slapd/back-ldbm/dblayer.c
@@ -3888,6 +3888,8 @@ static int txn_test_threadmain(void *param)
size_t counter = 0;
char keybuf[8192];
char databuf[8192];
+ int dbattempts = 0;
+ int dbmaxretries = 3;
PR_ASSERT(NULL != param);
li = (struct ldbminfo*)param;
@@ -3909,7 +3911,7 @@ wait_for_init:
if (priv->dblayer_stop_threads) {
goto end;
}
-
+ dbattempts++;
for (inst_obj = objset_first_obj(li->li_instance_set); inst_obj;
inst_obj = objset_next_obj(li->li_instance_set, inst_obj)) {
char **idx = NULL;
@@ -3917,6 +3919,8 @@ wait_for_init:
backend *be = inst->inst_be;
if (be->be_state != BE_STATE_STARTED) {
+ LDAPDebug0Args(LDAP_DEBUG_ANY,
+ "txn_test_threadmain: backend not started,
retrying\n");
object_release(inst_obj);
goto wait_for_init;
}
@@ -3924,6 +3928,8 @@ wait_for_init:
for (idx = cfg.indexes; idx && *idx; ++idx) {
DB *db = NULL;
if (be->be_state != BE_STATE_STARTED) {
+ LDAPDebug0Args(LDAP_DEBUG_ANY,
+ "txn_test_threadmain: backend not started,
retrying\n");
object_release(inst_obj);
goto wait_for_init;
}
@@ -3931,6 +3937,8 @@ wait_for_init:
if (!strcmp(*idx, "id2entry")) {
dblayer_get_id2entry(be, &db);
if (db == NULL) {
+ LDAPDebug0Args(LDAP_DEBUG_ANY,
+ "txn_test_threadmain: id2entry database not found
or not ready yet, retrying\n");
object_release(inst_obj);
goto wait_for_init;
}
@@ -3938,13 +3946,33 @@ wait_for_init:
struct attrinfo *ai = NULL;
ainfo_get(be, *idx, &ai);
if (NULL == ai) {
- object_release(inst_obj);
- goto wait_for_init;
+ if (dbattempts >= dbmaxretries) {
+ LDAPDebug1Arg(LDAP_DEBUG_ANY,
+ "txn_test_threadmain: index [%s] not found or
not ready yet, skipping\n",
+ *idx);
+ continue;
+ } else {
+ LDAPDebug1Arg(LDAP_DEBUG_ANY,
+ "txn_test_threadmain: index [%s] not found or
not ready yet, retrying\n",
+ *idx);
+ object_release(inst_obj);
+ goto wait_for_init;
+ }
}
if (dblayer_get_index_file(be, ai, &db, 0) || (NULL == db)) {
if ((NULL == db) && strcasecmp(*idx,
TXN_TEST_IDX_OK_IF_NULL)) {
- object_release(inst_obj);
- goto wait_for_init;
+ if (dbattempts >= dbmaxretries) {
+ LDAPDebug1Arg(LDAP_DEBUG_ANY,
+ "txn_test_threadmain: database file for
index [%s] not found or not ready yet, skipping\n",
+ *idx);
+ continue;
+ } else {
+ LDAPDebug1Arg(LDAP_DEBUG_ANY,
+ "txn_test_threadmain: database file for
index [%s] not found or not ready yet, retrying\n",
+ *idx);
+ object_release(inst_obj);
+ goto wait_for_init;
+ }
}
}
}
@@ -3955,6 +3983,9 @@ wait_for_init:
}
}
+ LDAPDebug0Args(LDAP_DEBUG_ANY, "txn_test_threadmain: starting main txn stress
loop\n");
+ print_ttilist(ttilist, tticnt);
+
while (!priv->dblayer_stop_threads) {
retry_txn:
init_ttilist(ttilist, tticnt);
commit bc428d413c29f0aba78674fb20b85846f67c1bc2
Author: Rich Megginson <rmeggins(a)redhat.com>
Date: Fri Jun 15 18:15:45 2012 -0600
Ticket #360 - ldapmodify returns Operations error - fix delete caching
https://fedorahosted.org/389/ticket/360
Resolves: Ticket #360
Bug Description: ldapmodify returns Operations error - fix delete caching
Reviewed by: ???
Branch: master
Fix Description: Previous commit was wrong. When retrying the op, have
to remove the tombstone, if any, from the cache first, then add back
the original entry.
Platforms tested: RHEL6 x86_64, Fedora 17
Flag Day: no
Doc impact: no
(cherry picked from commit ff30056700a150fec3e183e56bd23f89e4b43982)
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_delete.c
b/ldap/servers/slapd/back-ldbm/ldbm_delete.c
index 283dc64..6e6a5de 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_delete.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_delete.c
@@ -470,12 +470,6 @@ ldbm_back_delete( Slapi_PBlock *pb )
slapi_sdn_set_ndn_byval(&nscpEntrySDN,
slapi_sdn_get_ndn(slapi_entry_get_sdn(e->ep_entry)));
}
- /* reset original entry in cache */
- if (!e_in_cache) {
- CACHE_ADD(&inst->inst_cache, e, NULL);
- e_in_cache = 1;
- }
-
/* reset tombstone entry */
if (original_tombstone) {
if (tombstone_in_cache) {
@@ -492,6 +486,12 @@ ldbm_back_delete( Slapi_PBlock *pb )
}
}
+ /* reset original entry in cache */
+ if (!e_in_cache) {
+ CACHE_ADD(&inst->inst_cache, e, NULL);
+ e_in_cache = 1;
+ }
+
/* We're re-trying */
LDAPDebug0Args(LDAP_DEBUG_BACKLDBM,
"Delete Retrying Transaction\n");
commit bf6750af51ea7f9fe83966aa941a37843ab4c79b
Author: Rich Megginson <rmeggins(a)redhat.com>
Date: Wed Jun 13 14:28:51 2012 -0600
Ticket #360 - ldapmodify returns Operations error - fix delete caching
https://fedorahosted.org/389/ticket/360
Resolves: Ticket #360
Bug Description: ldapmodify returns Operations error - fix delete caching
Reviewed by: nhosoi (Thanks!)
Branch: master
Fix Description: Since creating a tombstone uses the same entryid as the
original entry to be deleted, we have to use cache_replace to replace the
existing entry with the tombstone. This is similar to modify and modrdn.
Platforms tested: RHEL6 x86_64, Fedora 17
Flag Day: no
Doc impact: no
(cherry picked from commit 79799c93959d9cc3f836423fd65a1aed9ea6f1f5)
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_delete.c
b/ldap/servers/slapd/back-ldbm/ldbm_delete.c
index 0427b45..283dc64 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_delete.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_delete.c
@@ -91,6 +91,7 @@ ldbm_back_delete( Slapi_PBlock *pb )
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;
entry_address *addr;
int addordel_flags = 0; /* passed to index_addordel */
char *entryusn_str = NULL;
@@ -187,6 +188,7 @@ ldbm_back_delete( Slapi_PBlock *pb )
/* retval is -1 */
goto error_return; /* error result sent by find_entry2modify() */
}
+ e_in_cache = 1; /* e is cached */
if ( slapi_entry_has_children( e->ep_entry ) )
{
@@ -468,6 +470,12 @@ ldbm_back_delete( Slapi_PBlock *pb )
slapi_sdn_set_ndn_byval(&nscpEntrySDN,
slapi_sdn_get_ndn(slapi_entry_get_sdn(e->ep_entry)));
}
+ /* reset original entry in cache */
+ if (!e_in_cache) {
+ CACHE_ADD(&inst->inst_cache, e, NULL);
+ e_in_cache = 1;
+ }
+
/* reset tombstone entry */
if (original_tombstone) {
if (tombstone_in_cache) {
@@ -593,6 +601,19 @@ ldbm_back_delete( Slapi_PBlock *pb )
LDAP_OPERATIONS_ERROR, retry_count);
goto error_return;
}
+ if (cache_replace( &inst->inst_cache, e, tombstone ) != 0 ) {
+ LDAPDebug0Args( LDAP_DEBUG_BACKLDBM, "ldbm_back_delete cache_replace
failed\n");
+ DEL_SET_ERROR(ldap_result_code,
+ LDAP_OPERATIONS_ERROR, retry_count);
+ retval= -1;
+ goto error_return;
+ } else {
+ e_in_cache = 0; /* e un-cached */
+ }
+ /* 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 );
}
else
{
@@ -1017,7 +1038,9 @@ ldbm_back_delete( Slapi_PBlock *pb )
/* delete from cache and clean up */
if (e) {
- CACHE_REMOVE(&inst->inst_cache, e);
+ if (e_in_cache) {
+ CACHE_REMOVE(&inst->inst_cache, e);
+ }
cache_unlock_entry(&inst->inst_cache, e);
CACHE_RETURN(&inst->inst_cache, &e);
e = NULL;
commit bcfa9e3aa2b8a2add085dae6e3e7416ee863ba80
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Mon Jun 18 10:24:50 2012 -0400
Coverity Fix
issue 12777
Bug Description: incorrectly used var r instead of rc
cherry-picked from ef4e3171c308cec2ca36e02cbc16d0f8da056a64
diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c
b/ldap/servers/plugins/replication/repl5_replica_config.c
index ca646e9..7d252ed 100644
--- a/ldap/servers/plugins/replication/repl5_replica_config.c
+++ b/ldap/servers/plugins/replication/repl5_replica_config.c
@@ -1278,8 +1278,7 @@ done:
slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: unable to
create cleanAllRUV "
"monitoring thread. Aborting task.\n");
}
-
- } else if(r == 0){ /* success */
+ } else if(rc == 0){ /* success */
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: Successfully
Finished.\n");
} else {
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: Task failed
(%d)\n",rc);