diff options
| author | Noriko Hosoi <nhosoi@redhat.com> | 2007-10-18 22:40:18 +0000 |
|---|---|---|
| committer | Noriko Hosoi <nhosoi@redhat.com> | 2007-10-18 22:40:18 +0000 |
| commit | 8eb7f7d52765adfe9cd9ff7793f81dfff0bd445b (patch) | |
| tree | ce91fa8ae6bc3318b8900b2e433ebc81d05f440b | |
| parent | d81e2fa8e34a5b8d0ceb9d35e106ba1b1cc66496 (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.c | 36 | ||||
| -rw-r--r-- | ldap/servers/plugins/replication/repl5_replica.c | 8 | ||||
| -rw-r--r-- | ldap/servers/slapd/back-ldbm/ldbm_add.c | 139 | ||||
| -rw-r--r-- | ldap/servers/slapd/back-ldbm/ldbm_delete.c | 42 | ||||
| -rw-r--r-- | ldap/servers/slapd/back-ldbm/ldbm_modify.c | 99 | ||||
| -rw-r--r-- | ldap/servers/slapd/back-ldbm/ldbm_modrdn.c | 30 | ||||
| -rw-r--r-- | ldap/servers/slapd/slapi-private.h | 58 |
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); |
