summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNoriko Hosoi <nhosoi@redhat.com>2007-10-18 22:40:18 +0000
committerNoriko Hosoi <nhosoi@redhat.com>2007-10-18 22:40:18 +0000
commit8eb7f7d52765adfe9cd9ff7793f81dfff0bd445b (patch)
treece91fa8ae6bc3318b8900b2e433ebc81d05f440b
parentd81e2fa8e34a5b8d0ceb9d35e106ba1b1cc66496 (diff)
Resolves #329951
Summary: MMR: Supplier does not respond anymore after many operations (deletes) Description: introduce OP_FLAG_REPL_RUV. It's set in repl5_replica.c if the entry is RUV. The operation should not be blocked at the backend SERIAL lock (this is achieved by having OP_FLAG_REPL_FIXUP set in the operation flag). But updating RUV has nothing to do with VLV, thus if the flag is set, it skips the VLV indexing.
-rw-r--r--ldap/servers/plugins/replication/repl5_plugins.c36
-rw-r--r--ldap/servers/plugins/replication/repl5_replica.c8
-rw-r--r--ldap/servers/slapd/back-ldbm/ldbm_add.c139
-rw-r--r--ldap/servers/slapd/back-ldbm/ldbm_delete.c42
-rw-r--r--ldap/servers/slapd/back-ldbm/ldbm_modify.c99
-rw-r--r--ldap/servers/slapd/back-ldbm/ldbm_modrdn.c30
-rw-r--r--ldap/servers/slapd/slapi-private.h58
7 files changed, 228 insertions, 184 deletions
diff --git a/ldap/servers/plugins/replication/repl5_plugins.c b/ldap/servers/plugins/replication/repl5_plugins.c
index 2c64382a..ad701b67 100644
--- a/ldap/servers/plugins/replication/repl5_plugins.c
+++ b/ldap/servers/plugins/replication/repl5_plugins.c
@@ -846,39 +846,39 @@ multimaster_postop_modrdn (Slapi_PBlock *pb)
static void
copy_operation_parameters(Slapi_PBlock *pb)
{
- Slapi_Operation *op = NULL;
- struct slapi_operation_parameters *op_params;
- supplier_operation_extension *opext;
+ Slapi_Operation *op = NULL;
+ struct slapi_operation_parameters *op_params;
+ supplier_operation_extension *opext;
Object *repl_obj;
Replica *replica;
-
+
repl_obj = replica_get_replica_for_op (pb);
/* we are only interested in the updates to replicas */
if (repl_obj)
{
/* we only save the original operation parameters for replicated operations
- since client operations don't go through urp engine and pblock data can be logged */
- slapi_pblock_get( pb, SLAPI_OPERATION, &op );
- PR_ASSERT (op);
+ since client operations don't go through urp engine and pblock data can be logged */
+ slapi_pblock_get( pb, SLAPI_OPERATION, &op );
+ PR_ASSERT (op);
replica = (Replica*)object_get_data (repl_obj);
- PR_ASSERT (replica);
+ PR_ASSERT (replica);
opext = (supplier_operation_extension*) repl_sup_get_ext (REPL_SUP_EXT_OP, op);
- if (operation_is_flag_set(op,OP_FLAG_REPLICATED) &&
+ if (operation_is_flag_set(op,OP_FLAG_REPLICATED) &&
!operation_is_flag_set(op, OP_FLAG_REPL_FIXUP))
- {
- slapi_pblock_get (pb, SLAPI_OPERATION_PARAMETERS, &op_params);
- opext->operation_parameters= operation_parameters_dup(op_params);
- }
-
- /* this condition is needed to avoid re-entering lock when
- ruv state is updated */
+ {
+ slapi_pblock_get (pb, SLAPI_OPERATION_PARAMETERS, &op_params);
+ opext->operation_parameters= operation_parameters_dup(op_params);
+ }
+
+ /* this condition is needed to avoid re-entering backend serial lock
+ when ruv state is updated */
if (!operation_is_flag_set(op, OP_FLAG_REPL_FIXUP))
{
- /* save replica generation in case it changes */
- opext->repl_gen = replica_get_generation (replica);
+ /* save replica generation in case it changes */
+ opext->repl_gen = replica_get_generation (replica);
}
object_release (repl_obj);
diff --git a/ldap/servers/plugins/replication/repl5_replica.c b/ldap/servers/plugins/replication/repl5_replica.c
index 40e84da4..702754e3 100644
--- a/ldap/servers/plugins/replication/repl5_replica.c
+++ b/ldap/servers/plugins/replication/repl5_replica.c
@@ -2258,7 +2258,8 @@ replica_write_ruv (Replica *r)
RUV_STORAGE_ENTRY_UNIQUEID,
repl_get_plugin_identity (PLUGIN_MULTIMASTER_REPLICATION),
/* Add OP_FLAG_TOMBSTONE_ENTRY so that this doesn't get logged in the Retro ChangeLog */
- OP_FLAG_REPLICATED | OP_FLAG_REPL_FIXUP | OP_FLAG_TOMBSTONE_ENTRY);
+ OP_FLAG_REPLICATED | OP_FLAG_REPL_FIXUP | OP_FLAG_TOMBSTONE_ENTRY |
+ OP_FLAG_REPL_RUV );
slapi_modify_internal_pb (pb);
slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &rc);
@@ -2732,7 +2733,8 @@ replica_create_ruv_tombstone(Replica *r)
e,
NULL /* controls */,
repl_get_plugin_identity(PLUGIN_MULTIMASTER_REPLICATION),
- OP_FLAG_TOMBSTONE_ENTRY | OP_FLAG_REPLICATED | OP_FLAG_REPL_FIXUP);
+ OP_FLAG_TOMBSTONE_ENTRY | OP_FLAG_REPLICATED | OP_FLAG_REPL_FIXUP |
+ OP_FLAG_REPL_RUV);
slapi_add_internal_pb(pb);
slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &return_value);
if (return_value == LDAP_SUCCESS)
@@ -3064,7 +3066,7 @@ replica_replace_ruv_tombstone(Replica *r)
NULL, /* controls */
RUV_STORAGE_ENTRY_UNIQUEID,
repl_get_plugin_identity (PLUGIN_MULTIMASTER_REPLICATION),
- OP_FLAG_REPLICATED | OP_FLAG_REPL_FIXUP);
+ OP_FLAG_REPLICATED | OP_FLAG_REPL_FIXUP | OP_FLAG_REPL_RUV);
slapi_modify_internal_pb (pb);
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_add.c b/ldap/servers/slapd/back-ldbm/ldbm_add.c
index 2a5a5cd7..764cff99 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_add.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_add.c
@@ -104,6 +104,7 @@ ldbm_back_add( Slapi_PBlock *pb )
int is_resurect_operation= 0;
int is_tombstone_operation= 0;
int is_fixup_operation= 0;
+ int is_ruv = 0; /* True if the current entry is RUV */
CSN *opcsn = NULL;
entry_address addr;
@@ -118,12 +119,13 @@ ldbm_back_add( Slapi_PBlock *pb )
is_resurect_operation= operation_is_flag_set(operation,OP_FLAG_RESURECT_ENTRY);
is_tombstone_operation= operation_is_flag_set(operation,OP_FLAG_TOMBSTONE_ENTRY);
- is_fixup_operation = operation_is_flag_set(operation,OP_FLAG_REPL_FIXUP);
+ is_fixup_operation = operation_is_flag_set(operation, OP_FLAG_REPL_FIXUP);
+ is_ruv = operation_is_flag_set(operation, OP_FLAG_REPL_RUV);
inst = (ldbm_instance *) be->be_instance_info;
-
- slapi_sdn_init(&sdn);
- slapi_sdn_init(&parentsdn);
+
+ slapi_sdn_init(&sdn);
+ slapi_sdn_init(&parentsdn);
/* Get rid of ldbm backend attributes that you are not allowed to specify yourself */
slapi_entry_delete_values( e, hassubordinates, NULL );
@@ -145,7 +147,7 @@ ldbm_back_add( Slapi_PBlock *pb )
dblock_acquired= 1;
}
- rc= 0;
+ rc= 0;
/*
* We are about to pass the last abandon test, so from now on we are
@@ -166,8 +168,8 @@ ldbm_back_add( Slapi_PBlock *pb )
rc= slapi_setbit_int(rc,SLAPI_RTN_BIT_FETCH_EXISTING_DN_ENTRY);
}
rc= slapi_setbit_int(rc,SLAPI_RTN_BIT_FETCH_EXISTING_UNIQUEID_ENTRY);
- rc= slapi_setbit_int(rc,SLAPI_RTN_BIT_FETCH_PARENT_ENTRY);
- while(rc!=0)
+ rc= slapi_setbit_int(rc,SLAPI_RTN_BIT_FETCH_PARENT_ENTRY);
+ while(rc!=0)
{
/* JCM - copying entries can be expensive... should optimize */
/*
@@ -175,20 +177,20 @@ ldbm_back_add( Slapi_PBlock *pb )
* backend pre-op plugin. To ensure a consistent snapshot of this state
* we wrap the reading of the entry with the dblock.
*/
- if(slapi_isbitset_int(rc,SLAPI_RTN_BIT_FETCH_EXISTING_UNIQUEID_ENTRY))
+ if(slapi_isbitset_int(rc,SLAPI_RTN_BIT_FETCH_EXISTING_UNIQUEID_ENTRY))
{
- /* Check if an entry with the intended uniqueid already exists. */
+ /* Check if an entry with the intended uniqueid already exists. */
done_with_pblock_entry(pb,SLAPI_ADD_EXISTING_UNIQUEID_ENTRY); /* Could be through this multiple times */
addr.dn = NULL;
addr.uniqueid = (char*)slapi_entry_get_uniqueid(e); /* jcm - cast away const */
ldap_result_code= get_copy_of_entry(pb, &addr, &txn, SLAPI_ADD_EXISTING_UNIQUEID_ENTRY, !is_replicated_operation);
}
- if(slapi_isbitset_int(rc,SLAPI_RTN_BIT_FETCH_EXISTING_DN_ENTRY))
+ if(slapi_isbitset_int(rc,SLAPI_RTN_BIT_FETCH_EXISTING_DN_ENTRY))
{
slapi_pblock_get( pb, SLAPI_ADD_TARGET, &dn );
- slapi_sdn_set_dn_byref(&sdn, dn);
+ slapi_sdn_set_dn_byref(&sdn, dn);
slapi_sdn_get_backend_parent(&sdn,&parentsdn,pb->pb_backend);
- /* Check if an entry with the intended DN already exists. */
+ /* Check if an entry with the intended DN already exists. */
done_with_pblock_entry(pb,SLAPI_ADD_EXISTING_DN_ENTRY); /* Could be through this multiple times */
addr.dn = dn;
addr.uniqueid = NULL;
@@ -206,24 +208,24 @@ ldbm_back_add( Slapi_PBlock *pb )
/* need to set parentsdn or parentuniqueid if either is not set? */
}
- /* Call the Backend Pre Add plugins */
+ /* Call the Backend Pre Add plugins */
slapi_pblock_set(pb, SLAPI_RESULT_CODE, &ldap_result_code);
- rc= plugin_call_plugins(pb, SLAPI_PLUGIN_BE_PRE_ADD_FN);
- if(rc==-1)
- {
+ rc= plugin_call_plugins(pb, SLAPI_PLUGIN_BE_PRE_ADD_FN);
+ if(rc==-1)
+ {
/*
* Plugin indicated some kind of failure,
* or that this Operation became a No-Op.
*/
slapi_pblock_get(pb, SLAPI_RESULT_CODE, &ldap_result_code);
- goto error_return;
- }
+ goto error_return;
+ }
/*
* (rc!=-1 && rc!= 0) means that the plugin changed things, so we go around
* the loop once again to get the new present state.
*/
/* JCMREPL - Warning: A Plugin could cause an infinite loop by always returning a result code that requires some action. */
- }
+ }
/*
* Originally (in the U-M LDAP 3.3 code), there was a comment near this
@@ -237,7 +239,7 @@ ldbm_back_add( Slapi_PBlock *pb )
/*
* Fetch the parent entry and acquire the cache lock.
*/
- if(have_parent_address(&parentsdn, operation->o_params.p.p_add.parentuniqueid))
+ if(have_parent_address(&parentsdn, operation->o_params.p.p_add.parentuniqueid))
{
addr.dn = (char*)slapi_sdn_get_dn (&parentsdn);
addr.uniqueid = operation->o_params.p.p_add.parentuniqueid;
@@ -255,13 +257,13 @@ ldbm_back_add( Slapi_PBlock *pb )
modify_init(&parent_modify_c,parententry);
}
- /* Check if the entry we have been asked to add already exists */
+ /* Check if the entry we have been asked to add already exists */
{
Slapi_Entry *entry;
slapi_pblock_get( pb, SLAPI_ADD_EXISTING_DN_ENTRY, &entry);
if ( entry != NULL )
{
- /* The entry already exists */
+ /* The entry already exists */
ldap_result_code= LDAP_ALREADY_EXISTS;
goto error_return;
}
@@ -283,7 +285,7 @@ ldbm_back_add( Slapi_PBlock *pb )
if ( ancestorentry != NULL )
{
int sentreferral= check_entry_for_referral(pb, ancestorentry->ep_entry, backentry_get_ndn(ancestorentry), "ldbm_back_add");
- cache_return( &inst->inst_cache, &ancestorentry );
+ cache_return( &inst->inst_cache, &ancestorentry );
if(sentreferral)
{
ldap_result_code= -1; /* The result was sent by check_entry_for_referral */
@@ -316,7 +318,7 @@ ldbm_back_add( Slapi_PBlock *pb )
tombstoneentry = find_entry2modify( pb, be, &addr, NULL );
if ( tombstoneentry==NULL )
{
- ldap_result_code= -1;
+ ldap_result_code= -1;
goto error_return; /* error result sent by find_entry2modify() */
}
tombstone_in_cache = 1;
@@ -324,7 +326,7 @@ ldbm_back_add( Slapi_PBlock *pb )
addingentry = backentry_dup( tombstoneentry );
if ( addingentry==NULL )
{
- ldap_result_code= LDAP_OPERATIONS_ERROR;
+ ldap_result_code= LDAP_OPERATIONS_ERROR;
goto error_return;
}
/*
@@ -405,8 +407,8 @@ ldbm_back_add( Slapi_PBlock *pb )
addingentry = backentry_init( e );
if ( ( addingentry->ep_id = next_id( be ) ) >= MAXID ) {
LDAPDebug( LDAP_DEBUG_ANY,
- "add: maximum ID reached, cannot add entry to "
- "backend '%s'", be->be_name, 0, 0 );
+ "add: maximum ID reached, cannot add entry to "
+ "backend '%s'", be->be_name, 0, 0 );
ldap_result_code = LDAP_OPERATIONS_ERROR;
goto error_return;
}
@@ -436,11 +438,11 @@ ldbm_back_add( Slapi_PBlock *pb )
/* Directly add the entry as a tombstone */
/*
* 1) If the entry has an existing DN, change it to be
- * "nsuniqueid=<uniqueid>, <old dn>"
+ * "nsuniqueid=<uniqueid>, <old dn>"
* 2) Add the objectclass value "tombstone" and arrange for only
- * that value to be indexed.
+ * that value to be indexed.
* 3) If the parent entry was found, set the nsparentuniqueid
- * attribute to be the unique id of that parent.
+ * attribute to be the unique id of that parent.
*/
char *untombstoned_dn = slapi_entry_get_dn(e);
if (NULL == untombstoned_dn)
@@ -476,13 +478,13 @@ ldbm_back_add( Slapi_PBlock *pb )
struct backentry *ancestorentry;
LDAPDebug( LDAP_DEBUG_TRACE,
- "parent does not exist, pdn = %s\n",
- slapi_sdn_get_dn(&parentsdn), 0, 0 );
+ "parent does not exist, pdn = %s\n",
+ slapi_sdn_get_dn(&parentsdn), 0, 0 );
ancestorentry = dn2ancestor(be, &parentsdn, &ancestordn, &txn, &err );
cache_return( &inst->inst_cache, &ancestorentry );
- ldap_result_code= LDAP_NO_SUCH_OBJECT;
+ ldap_result_code= LDAP_NO_SUCH_OBJECT;
ldap_result_matcheddn= slapi_ch_strdup((char *)slapi_sdn_get_dn(&ancestordn)); /* jcm - cast away const. */
slapi_sdn_done(&ancestordn);
goto error_return;
@@ -502,8 +504,8 @@ ldbm_back_add( Slapi_PBlock *pb )
if ( !isroot && !is_replicated_operation)
{
LDAPDebug( LDAP_DEBUG_TRACE, "no parent & not root\n",
- 0, 0, 0 );
- ldap_result_code= LDAP_INSUFFICIENT_ACCESS;
+ 0, 0, 0 );
+ ldap_result_code= LDAP_INSUFFICIENT_ACCESS;
goto error_return;
}
parententry = NULL;
@@ -527,7 +529,7 @@ ldbm_back_add( Slapi_PBlock *pb )
/*
* add the parentid, entryid and entrydn operational attributes
*/
- add_update_entry_operational_attributes(addingentry, pid);
+ add_update_entry_operational_attributes(addingentry, pid);
}
/* Tentatively add the entry to the cache. We do this after adding any
@@ -560,7 +562,7 @@ ldbm_back_add( Slapi_PBlock *pb )
retval = parent_update_on_childchange(&parent_modify_c,1,NULL); /* 1==add */\
/* The modify context now contains info needed later */
if (0 != retval) {
- ldap_result_code= LDAP_OPERATIONS_ERROR;
+ ldap_result_code= LDAP_OPERATIONS_ERROR;
goto error_return;
}
parent_found = 1;
@@ -577,10 +579,10 @@ ldbm_back_add( Slapi_PBlock *pb )
/* We're re-trying */
LDAPDebug( LDAP_DEBUG_TRACE, "Add Retrying Transaction\n", 0, 0, 0 );
#ifndef LDBM_NO_BACKOFF_DELAY
- {
- PRIntervalTime interval;
- interval = PR_MillisecondsToInterval(slapi_rand() % 100);
- DS_Sleep(interval);
+ {
+ PRIntervalTime interval;
+ interval = PR_MillisecondsToInterval(slapi_rand() % 100);
+ DS_Sleep(interval);
}
#endif
}
@@ -682,7 +684,7 @@ ldbm_back_add( Slapi_PBlock *pb )
}
if (retval != 0) {
LDAPDebug( LDAP_DEBUG_ANY, "add: attempt to index %lu failed\n",
- (u_long)addingentry->ep_id, 0, 0 );
+ (u_long)addingentry->ep_id, 0, 0 );
if (LDBM_OS_ERR_IS_DISKFULL(retval)) {
disk_full = 1;
ldap_result_code= LDAP_OPERATIONS_ERROR;
@@ -705,38 +707,41 @@ ldbm_back_add( Slapi_PBlock *pb )
retval, (msg = dblayer_strerror( retval )) ? msg : "", 0 );
if (LDBM_OS_ERR_IS_DISKFULL(retval)) {
disk_full = 1;
- ldap_result_code= LDAP_OPERATIONS_ERROR;
+ ldap_result_code= LDAP_OPERATIONS_ERROR;
goto diskfull_return;
}
- ldap_result_code= LDAP_OPERATIONS_ERROR;
+ ldap_result_code= LDAP_OPERATIONS_ERROR;
goto error_return;
}
}
- /*
- * Update the Virtual List View indexes
- */
- retval= vlv_update_all_indexes(&txn, be, pb, NULL, addingentry);
- if (DB_LOCK_DEADLOCK == retval)
+ /*
+ * Update the Virtual List View indexes
+ */
+ if (!is_ruv)
{
- LDAPDebug( LDAP_DEBUG_ARGS, "add DEADLOCK vlv_update_index\n", 0, 0, 0 );
- /* Retry txn */
- continue;
- }
- if (0 != retval) {
- LDAPDebug( LDAP_DEBUG_TRACE, "vlv_update_index failed, err=%d %s\n",
- retval, (msg = dblayer_strerror( retval )) ? msg : "", 0 );
- if (LDBM_OS_ERR_IS_DISKFULL(retval)) {
- disk_full = 1;
+ retval= vlv_update_all_indexes(&txn, be, pb, NULL, addingentry);
+ if (DB_LOCK_DEADLOCK == retval) {
+ LDAPDebug( LDAP_DEBUG_ARGS,
+ "add DEADLOCK vlv_update_index\n", 0, 0, 0 );
+ /* Retry txn */
+ continue;
+ }
+ if (0 != retval) {
+ LDAPDebug( LDAP_DEBUG_TRACE,
+ "vlv_update_index failed, err=%d %s\n",
+ retval, (msg = dblayer_strerror( retval )) ? msg : "", 0 );
+ if (LDBM_OS_ERR_IS_DISKFULL(retval)) {
+ disk_full = 1;
+ ldap_result_code= LDAP_OPERATIONS_ERROR;
+ goto diskfull_return;
+ }
ldap_result_code= LDAP_OPERATIONS_ERROR;
- goto diskfull_return;
+ goto error_return;
}
- ldap_result_code= LDAP_OPERATIONS_ERROR;
- goto error_return;
}
- if (retval == 0 ) {
+ if (retval == 0) {
break;
}
-
}
if (retry_count == RETRY_TIMES) {
/* Failed */
@@ -760,9 +765,9 @@ ldbm_back_add( Slapi_PBlock *pb )
if (cache_replace( &inst->inst_cache, tombstoneentry, addingentry ) != 0 )
{
/* This happens if the dn of addingentry already exists */
- ldap_result_code= LDAP_ALREADY_EXISTS;
+ ldap_result_code= LDAP_ALREADY_EXISTS;
cache_unlock_entry( &inst->inst_cache, tombstoneentry );
- goto error_return;
+ goto error_return;
}
/*
* The tombstone was locked down in the cache... we can
@@ -844,9 +849,9 @@ common_return:
{
dblayer_unlock_backend(be);
}
- if(ldap_result_code!=-1)
+ if(ldap_result_code!=-1)
{
- slapi_send_ldap_result( pb, ldap_result_code, ldap_result_matcheddn, ldap_result_message, 0, NULL );
+ slapi_send_ldap_result( pb, ldap_result_code, ldap_result_matcheddn, ldap_result_message, 0, NULL );
}
slapi_sdn_done(&sdn);
slapi_sdn_done(&parentsdn);
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_delete.c b/ldap/servers/slapd/back-ldbm/ldbm_delete.c
index f9e2520e..6e6ecea2 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_delete.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_delete.c
@@ -73,6 +73,7 @@ ldbm_back_delete( Slapi_PBlock *pb )
Slapi_Operation *operation;
CSN *opcsn = NULL;
int is_fixup_operation = 0;
+ int is_ruv = 0; /* True if the current entry is RUV */
int is_replicated_operation= 0;
int is_tombstone_entry = 0; /* True if the current entry is alreday a tombstone */
int delete_tombstone_entry = 0; /* We must remove the given tombstone entry from the DB */
@@ -95,7 +96,8 @@ ldbm_back_delete( Slapi_PBlock *pb )
slapi_log_error (SLAPI_LOG_TRACE, "ldbm_back_delete", "enter conn=%d op=%d\n", pb->pb_conn->c_connid, operation->o_opid);
}
- is_fixup_operation = operation_is_flag_set(operation,OP_FLAG_REPL_FIXUP);
+ is_fixup_operation = operation_is_flag_set(operation, OP_FLAG_REPL_FIXUP);
+ is_ruv = operation_is_flag_set(operation, OP_FLAG_REPL_RUV);
delete_tombstone_entry = operation_is_flag_set(operation, OP_FLAG_TOMBSTONE_ENTRY);
inst = (ldbm_instance *) be->be_instance_info;
@@ -469,7 +471,8 @@ ldbm_back_delete( Slapi_PBlock *pb )
ldap_result_code= LDAP_OPERATIONS_ERROR;
goto error_return;
}
- } else if (delete_tombstone_entry)
+ } /* create_tombstone_entry */
+ else if (delete_tombstone_entry)
{
/*
* We need to remove the Tombstone entry from the remaining indexes:
@@ -521,7 +524,7 @@ ldbm_back_delete( Slapi_PBlock *pb )
goto error_return;
}
}
- }
+ } /* delete_tombstone_entry */
if (parent_found) {
/* Push out the db modifications from the parent entry */
@@ -536,32 +539,31 @@ ldbm_back_delete( Slapi_PBlock *pb )
LDAPDebug( LDAP_DEBUG_TRACE, "delete 3 BAD, err=%d %s\n",
retval, (msg = dblayer_strerror( retval )) ? msg : "", 0 );
if (LDBM_OS_ERR_IS_DISKFULL(retval)) disk_full = 1;
- ldap_result_code= LDAP_OPERATIONS_ERROR;
+ ldap_result_code= LDAP_OPERATIONS_ERROR;
goto error_return;
}
}
/*
* first check if searchentry needs to be removed
* Remove the entry from the Virtual List View indexes.
- *
*/
- if(!delete_tombstone_entry &&
- !vlv_delete_search_entry(pb,e->ep_entry,inst)) {
+ if (!delete_tombstone_entry && !is_ruv &&
+ !vlv_delete_search_entry(pb,e->ep_entry,inst)) {
retval = vlv_update_all_indexes(&txn, be, pb, e, NULL);
+
+ if (DB_LOCK_DEADLOCK == retval)
+ {
+ LDAPDebug( LDAP_DEBUG_ARGS, "delete DEADLOCK vlv_update_index\n", 0, 0, 0 );
+ /* Retry txn */
+ continue;
+ }
+ if (retval != 0 ) {
+ if (LDBM_OS_ERR_IS_DISKFULL(retval)) disk_full = 1;
+ ldap_result_code= LDAP_OPERATIONS_ERROR;
+ goto error_return;
+ }
}
-
- if (DB_LOCK_DEADLOCK == retval)
- {
- LDAPDebug( LDAP_DEBUG_ARGS, "delete DEADLOCK vlv_update_index\n", 0, 0, 0 );
- /* Retry txn */
- continue;
- }
- if (retval != 0 ) {
- if (LDBM_OS_ERR_IS_DISKFULL(retval)) disk_full = 1;
- ldap_result_code= LDAP_OPERATIONS_ERROR;
- goto error_return;
- }
- if (retval == 0 ) {
+ if (retval == 0 ) {
break;
}
}
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modify.c b/ldap/servers/slapd/back-ldbm/ldbm_modify.c
index 470c40d5..36e84230 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_modify.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_modify.c
@@ -131,12 +131,18 @@ int modify_update_all(backend *be, Slapi_PBlock *pb,
back_txn *txn)
{
static char *function_name = "modify_update_all";
+ Slapi_Operation *operation;
+ int is_ruv = 0; /* True if the current entry is RUV */
int retval = 0;
- /*
- * Update the ID to Entry index.
- * Note that id2entry_add replaces the entry, so the Entry ID stays the same.
- */
+ if (pb) { /* pb could be NULL if it's called from import */
+ slapi_pblock_get( pb, SLAPI_OPERATION, &operation );
+ is_ruv = operation_is_flag_set(operation, OP_FLAG_REPL_RUV);
+ }
+ /*
+ * Update the ID to Entry index.
+ * Note that id2entry_add replaces the entry, so the Entry ID stays the same.
+ */
retval = id2entry_add( be, mc->new_entry, txn );
if ( 0 != retval ) {
if (DB_LOCK_DEADLOCK != retval)
@@ -153,13 +159,13 @@ int modify_update_all(backend *be, Slapi_PBlock *pb,
}
goto error;
}
- /*
- * Remove the old entry from the Virtual List View indexes.
- * Add the new entry to the Virtual List View indexes.
+ /*
+ * Remove the old entry from the Virtual List View indexes.
+ * Add the new entry to the Virtual List View indexes.
* Because the VLV code calls slapi_filter_test(), which requires a pb (why?),
* we allow the caller sans pb to get everything except vlv indexing.
- */
- if (NULL != pb) {
+ */
+ if (NULL != pb && !is_ruv) {
retval= vlv_update_all_indexes(txn, be, pb, mc->old_entry, mc->new_entry);
if ( 0 != retval ) {
if (DB_LOCK_DEADLOCK != retval)
@@ -189,7 +195,7 @@ ldbm_back_modify( Slapi_PBlock *pb )
char *errbuf = NULL;
int retry_count = 0;
int disk_full = 0;
- int ldap_result_code= LDAP_SUCCESS;
+ int ldap_result_code= LDAP_SUCCESS;
char *ldap_result_message= NULL;
int rc = 0;
Slapi_Operation *operation;
@@ -198,6 +204,7 @@ ldbm_back_modify( Slapi_PBlock *pb )
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;
@@ -208,7 +215,8 @@ ldbm_back_modify( Slapi_PBlock *pb )
slapi_pblock_get( pb, SLAPI_PARENT_TXN, (void**)&parent_txn );
slapi_pblock_get( pb, SLAPI_OPERATION, &operation );
slapi_pblock_get (pb, SLAPI_IS_REPLICATED_OPERATION, &repl_op);
- is_fixup_operation = operation_is_flag_set(operation,OP_FLAG_REPL_FIXUP);
+ is_fixup_operation = operation_is_flag_set(operation, OP_FLAG_REPL_FIXUP);
+ is_ruv = operation_is_flag_set(operation, OP_FLAG_REPL_RUV);
inst = (ldbm_instance *) be->be_instance_info;
dblayer_txn_init(li,&txn);
@@ -221,15 +229,14 @@ ldbm_back_modify( Slapi_PBlock *pb )
* operations that the URP code in the Replication
* plugin generates.
*/
- if(SERIALLOCK(li) && !operation_is_flag_set(operation,OP_FLAG_REPL_FIXUP))
- {
+ if(SERIALLOCK(li) && !operation_is_flag_set(operation,OP_FLAG_REPL_FIXUP)) {
dblayer_lock_backend(be);
dblock_acquired= 1;
}
/* find and lock the entry we are about to modify */
if ( (e = find_entry2modify( pb, be, addr, NULL )) == NULL ) {
- ldap_result_code= -1;
+ ldap_result_code= -1;
goto error_return; /* error result sent by find_entry2modify() */
}
@@ -260,7 +267,7 @@ ldbm_back_modify( Slapi_PBlock *pb )
/* create a copy of the entry and apply the changes to it */
if ( (ec = backentry_dup( e )) == NULL ) {
- ldap_result_code= LDAP_OPERATIONS_ERROR;
+ ldap_result_code= LDAP_OPERATIONS_ERROR;
goto error_return;
}
@@ -276,10 +283,10 @@ ldbm_back_modify( Slapi_PBlock *pb )
{
Slapi_Mods smods;
- CSN *csn = operation_get_csn(operation);
+ CSN *csn = operation_get_csn(operation);
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));
+ 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.,
@@ -356,8 +363,8 @@ ldbm_back_modify( Slapi_PBlock *pb )
dblayer_txn_abort(li,&txn);
LDAPDebug( LDAP_DEBUG_TRACE, "Modify Retrying Transaction\n", 0, 0, 0 );
#ifndef LDBM_NO_BACKOFF_DELAY
- {
- PRIntervalTime interval;
+ {
+ PRIntervalTime interval;
interval = PR_MillisecondsToInterval(slapi_rand() % 100);
DS_Sleep(interval);
}
@@ -373,10 +380,10 @@ ldbm_back_modify( Slapi_PBlock *pb )
goto error_return;
}
- /*
- * Update the ID to Entry index.
- * Note that id2entry_add replaces the entry, so the Entry ID stays the same.
- */
+ /*
+ * Update the ID to Entry index.
+ * Note that id2entry_add replaces the entry, so the Entry ID stays the same.
+ */
retval = id2entry_add( be, ec, &txn );
if (DB_LOCK_DEADLOCK == retval)
{
@@ -404,37 +411,41 @@ ldbm_back_modify( Slapi_PBlock *pb )
ldap_result_code= LDAP_OPERATIONS_ERROR;
goto error_return;
}
- /*
- * Remove the old entry from the Virtual List View indexes.
- * Add the new entry to the Virtual List View indexes.
- */
- retval= vlv_update_all_indexes(&txn, be, pb, e, ec);
- if (DB_LOCK_DEADLOCK == retval)
- {
- /* Abort and re-try */
- continue;
- }
- if (0 != retval) {
- LDAPDebug( LDAP_DEBUG_ANY, "vlv_update_index failed, err=%d %s\n",
- retval, (msg = dblayer_strerror( retval )) ? msg : "", 0 );
- if (LDBM_OS_ERR_IS_DISKFULL(retval)) disk_full = 1;
- ldap_result_code= LDAP_OPERATIONS_ERROR;
- goto error_return;
- }
+ /*
+ * Remove the old entry from the Virtual List View indexes.
+ * Add the new entry to the Virtual List View indexes.
+ * If the entry is ruv, no need to update vlv.
+ */
+ if (!is_ruv) {
+ retval= vlv_update_all_indexes(&txn, be, pb, e, ec);
+ if (DB_LOCK_DEADLOCK == retval)
+ {
+ /* Abort and re-try */
+ continue;
+ }
+ if (0 != retval) {
+ LDAPDebug( LDAP_DEBUG_ANY,
+ "vlv_update_index failed, err=%d %s\n",
+ retval, (msg = dblayer_strerror( retval )) ? msg : "", 0 );
+ if (LDBM_OS_ERR_IS_DISKFULL(retval)) disk_full = 1;
+ ldap_result_code= LDAP_OPERATIONS_ERROR;
+ goto error_return;
+ }
+ }
if (0 == retval) {
break;
}
}
if (retry_count == RETRY_TIMES) {
LDAPDebug( LDAP_DEBUG_ANY, "Retry count exceeded in modify\n", 0, 0, 0 );
- ldap_result_code= LDAP_OPERATIONS_ERROR;
+ ldap_result_code= LDAP_OPERATIONS_ERROR;
goto error_return;
}
if (cache_replace( &inst->inst_cache, e, ec ) != 0 ) {
- ldap_result_code= LDAP_OPERATIONS_ERROR;
- goto error_return;
+ ldap_result_code= LDAP_OPERATIONS_ERROR;
+ goto error_return;
}
postentry = slapi_entry_dup( ec->ep_entry );
@@ -473,7 +484,7 @@ error_return:
}
else
{
- backentry_free(&ec);
+ backentry_free(&ec);
}
if ( postentry != NULL )
{
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c b/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
index 099f2572..cc5e78bb 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
@@ -113,7 +113,7 @@ ldbm_back_modrdn( Slapi_PBlock *pb )
slapi_pblock_get( pb, SLAPI_REQUESTOR_ISROOT, &isroot );
slapi_pblock_get( pb, SLAPI_OPERATION, &operation );
slapi_pblock_get( pb, SLAPI_IS_REPLICATED_OPERATION, &is_replicated_operation );
- is_fixup_operation = operation_is_flag_set(operation,OP_FLAG_REPL_FIXUP);
+ is_fixup_operation = operation_is_flag_set(operation, OP_FLAG_REPL_FIXUP);
if (pb->pb_conn)
{
@@ -1127,8 +1127,12 @@ modrdn_rename_entry_update_indexes(back_txn *ptxn, Slapi_PBlock *pb, struct ldbm
ldbm_instance *inst;
int retval= 0;
char *msg;
+ Slapi_Operation *operation;
+ int is_ruv = 0; /* True if the current entry is RUV */
- slapi_pblock_get( pb, SLAPI_BACKEND, &be);
+ slapi_pblock_get( pb, SLAPI_BACKEND, &be );
+ slapi_pblock_get( pb, SLAPI_OPERATION, &operation );
+ is_ruv = operation_is_flag_set(operation, OP_FLAG_REPL_RUV);
inst = (ldbm_instance *) be->be_instance_info;
/*
@@ -1206,17 +1210,21 @@ modrdn_rename_entry_update_indexes(back_txn *ptxn, Slapi_PBlock *pb, struct ldbm
/*
* Remove the old entry from the Virtual List View indexes.
* Add the new entry to the Virtual List View indexes.
+ * If ruv, we don't have to update vlv.
*/
- retval= vlv_update_all_indexes(ptxn, be, pb, e, ec);
- if (DB_LOCK_DEADLOCK == retval)
+ if (!is_ruv)
{
- /* Abort and re-try */
- goto error_return;
- }
- if (retval != 0)
- {
- LDAPDebug( LDAP_DEBUG_TRACE, "vlv_update_all_indexes failed, err=%d %s\n", retval, (msg = dblayer_strerror( retval )) ? msg : "", 0 );
- goto error_return;
+ retval= vlv_update_all_indexes(ptxn, be, pb, e, ec);
+ if (DB_LOCK_DEADLOCK == retval)
+ {
+ /* Abort and re-try */
+ goto error_return;
+ }
+ if (retval != 0)
+ {
+ LDAPDebug( LDAP_DEBUG_TRACE, "vlv_update_all_indexes failed, err=%d %s\n", retval, (msg = dblayer_strerror( retval )) ? msg : "", 0 );
+ goto error_return;
+ }
}
if (cache_replace( &inst->inst_cache, e, ec ) != 0 ) {
retval= -1;
diff --git a/ldap/servers/slapd/slapi-private.h b/ldap/servers/slapd/slapi-private.h
index 320f392e..834ce46d 100644
--- a/ldap/servers/slapd/slapi-private.h
+++ b/ldap/servers/slapd/slapi-private.h
@@ -382,27 +382,43 @@ slapi_filter_to_string_internal( const struct slapi_filter *f, char *buf, size_t
/* operation.c */
-#define OP_FLAG_PS 0x00001
-#define OP_FLAG_PS_CHANGESONLY 0x00002
-#define OP_FLAG_GET_EFFECTIVE_RIGHTS 0x00004
-#define OP_FLAG_REPLICATED 0x00008 /* A Replicated Operation */
-#define OP_FLAG_REPL_FIXUP 0x00010 /* A Fixup Operation, generated as a
- * consequence of a Replicated Operation. */
-#define OP_FLAG_INTERNAL 0x00020 /* An operation generated by the core
- * server or a plugin. */
-#define OP_FLAG_ACTION_LOG_ACCESS 0x00040
-#define OP_FLAG_ACTION_LOG_AUDIT 0x00080
-#define OP_FLAG_ACTION_SCHEMA_CHECK 0x00100
-#define OP_FLAG_ACTION_LOG_CHANGES 0x00200
-#define OP_FLAG_ACTION_INVOKE_FOR_REPLOP 0x00400
-#define OP_FLAG_NEVER_CHAIN SLAPI_OP_FLAG_NEVER_CHAIN /* 0x0800 */
-#define OP_FLAG_TOMBSTONE_ENTRY 0x01000
-#define OP_FLAG_RESURECT_ENTRY 0x02000
-#define OP_FLAG_LEGACY_REPLICATION_DN 0x04000 /* Operation done by legacy replication DN */
-#define OP_FLAG_ACTION_NOLOG 0x08000 /* Do not log the entry in audit log or
- * change log */
-#define OP_FLAG_SKIP_MODIFIED_ATTRS 0x10000 /* Do not update the modifiersname,
- * modifiedtimestamp, etc. attributes */
+#define OP_FLAG_PS 0x00001
+#define OP_FLAG_PS_CHANGESONLY 0x00002
+#define OP_FLAG_GET_EFFECTIVE_RIGHTS 0x00004
+#define OP_FLAG_REPLICATED 0x00008 /* A Replicated Operation */
+#define OP_FLAG_REPL_FIXUP 0x00010 /* A Fixup Operation,
+ * generated as a consequence
+ * of a Replicated Operation.
+ */
+#define OP_FLAG_INTERNAL 0x00020 /* An operation generated by
+ * the core server or a plugin.
+ */
+#define OP_FLAG_ACTION_LOG_ACCESS 0x00040
+#define OP_FLAG_ACTION_LOG_AUDIT 0x00080
+#define OP_FLAG_ACTION_SCHEMA_CHECK 0x00100
+#define OP_FLAG_ACTION_LOG_CHANGES 0x00200
+#define OP_FLAG_ACTION_INVOKE_FOR_REPLOP 0x00400
+#define OP_FLAG_NEVER_CHAIN SLAPI_OP_FLAG_NEVER_CHAIN /* 0x0800 */
+#define OP_FLAG_TOMBSTONE_ENTRY 0x01000
+#define OP_FLAG_RESURECT_ENTRY 0x02000
+#define OP_FLAG_LEGACY_REPLICATION_DN 0x04000 /* Operation done by legacy
+ * replication DN
+ */
+#define OP_FLAG_ACTION_NOLOG 0x08000 /* Do not log the entry in
+ * audit log or change log
+ */
+#define OP_FLAG_SKIP_MODIFIED_ATTRS 0x10000 /* Do not update the
+ * modifiersname,
+ * modifiedtimestamp, etc.
+ * attributes
+ */
+#define OP_FLAG_REPL_RUV 0x20000 /* Flag to tell to the backend
+ * that the entry to be added/
+ * modified is RUV. This info
+ * is used to skip VLV op.
+ * (see #329951)
+ */
+
CSN *operation_get_csn(Slapi_Operation *op);
void operation_set_csn(Slapi_Operation *op,CSN *csn);