From: Jong Hyuk Choi Date: Wed, 10 Sep 2003 17:03:01 +0000 (+0000) Subject: add bdb_get_commit_csn() for use in bdb_search X-Git-Tag: OPENLDAP_REL_ENG_2_1_MP~739 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=d5be4896a36d2b2b8e81873ea10eb5d73000a7a8;p=openldap add bdb_get_commit_csn() for use in bdb_search --- diff --git a/servers/slapd/back-bdb/ctxcsn.c b/servers/slapd/back-bdb/ctxcsn.c index 9c0e2999a9..a222d0ff1a 100644 --- a/servers/slapd/back-bdb/ctxcsn.c +++ b/servers/slapd/back-bdb/ctxcsn.c @@ -27,6 +27,7 @@ #include #include +#include "lutil.h" #include "back-bdb.h" #include "external.h" @@ -70,12 +71,12 @@ bdb_csn_commit( 1, locker, &ctxcsn_lock ); *ctxcsn_e = ctxcsn_ei->bei_e; - bdb_cache_entry_db_relock( bdb->bi_dbenv, locker, ctxcsn_ei, 1, 0, &ctxcsn_lock ); max_committed_csn = slap_get_commit_csn( op ); - if ( max_committed_csn == NULL ) + if ( max_committed_csn == NULL ) { return BDB_CSN_COMMIT; + } *ctxcsn_added = 0; @@ -98,7 +99,7 @@ bdb_csn_commit( ret = slap_mods_check( modlist, 1, &rs->sr_text, textbuf, textlen, NULL ); - if ( rc != LDAP_SUCCESS ) { + if ( ret != LDAP_SUCCESS ) { #ifdef NEW_LOGGING LDAP_LOG( OPERATION, ERR, "bdb_csn_commit: mods check (%s)\n", rs->sr_text, 0, 0 ); @@ -108,6 +109,8 @@ bdb_csn_commit( #endif } + bdb_cache_entry_db_relock( bdb->bi_dbenv, locker, ctxcsn_ei, 1, 0, &ctxcsn_lock ); + ret = bdb_modify_internal( op, tid, modlist, *ctxcsn_e, &rs->sr_text, textbuf, textlen ); if ( ret != LDAP_SUCCESS ) { @@ -121,9 +124,9 @@ bdb_csn_commit( switch( ret ) { case DB_LOCK_DEADLOCK: case DB_LOCK_NOTGRANTED: - return BDB_CSN_ABORT; - default: goto rewind; + default: + return BDB_CSN_ABORT; } } @@ -224,6 +227,13 @@ bdb_csn_commit( break; case DB_LOCK_DEADLOCK: case DB_LOCK_NOTGRANTED: +#ifdef NEW_LOGGING + LDAP_LOG( OPERATION, ERR, + "bdb_csn_commit : bdb_dn2entry retry\n", 0, 0, 0 ); +#else + Debug( LDAP_DEBUG_TRACE, + "bdb_csn_commit : bdb_dn2entry retry\n", 0, 0, 0 ); +#endif goto rewind; case LDAP_BUSY: rs->sr_err = rc; @@ -241,3 +251,142 @@ rewind : slap_rewind_commit_csn( op ); return BDB_CSN_RETRY; } + +int +bdb_get_commit_csn( + Operation *op, + SlapReply *rs, + struct berval **search_context_csn, + u_int32_t locker, + DB_LOCK *ctxcsn_lock +) +{ + struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; + struct berval ctxcsn_rdn = BER_BVNULL; + struct berval ctxcsn_ndn = BER_BVNULL; + struct berval csn = BER_BVNULL; + struct berval ctx_nrdn = BER_BVC( "cn=ldapsync" ); + EntryInfo *ctxcsn_ei = NULL; + EntryInfo *suffix_ei = NULL; + Entry *ctxcsn_e = NULL; + DB_TXN *ltid = NULL; + Attribute *csn_a; + char substr[67]; + char gid[DB_XIDDATASIZE]; + char csnbuf[ LDAP_LUTIL_CSNSTR_BUFSIZE ]; + int num_retries = 0; + int ctxcsn_added = 0; + int rc; + + if ( op->o_sync_mode != SLAP_SYNC_NONE ) { + if ( op->o_bd->syncinfo ) { + sprintf( substr, "cn=syncrepl%d", op->o_bd->syncinfo->id ); + ber_str2bv( substr, strlen( substr ), 0, &ctxcsn_rdn ); + build_new_dn( &ctxcsn_ndn, &op->o_bd->be_nsuffix[0], &ctxcsn_rdn ); + } else { + ber_str2bv( "cn=ldapsync", strlen("cn=ldapsync"), 0, &ctxcsn_rdn ); + build_new_dn( &ctxcsn_ndn, &op->o_bd->be_nsuffix[0], &ctxcsn_rdn ); + } + +ctxcsn_retry : + rs->sr_err = bdb_dn2entry( op, NULL, &ctxcsn_ndn, &ctxcsn_ei, + 0, locker, ctxcsn_lock ); + switch(rs->sr_err) { + case 0: + ch_free( ctxcsn_ndn.bv_val ); + if ( ctxcsn_ei ) { + ctxcsn_e = ctxcsn_ei->bei_e; + } + break; + case LDAP_BUSY: + ch_free( ctxcsn_ndn.bv_val ); + LOCK_ID_FREE (bdb->bi_dbenv, locker ); + return LDAP_BUSY; + case DB_LOCK_DEADLOCK: + case DB_LOCK_NOTGRANTED: + goto ctxcsn_retry; + case DB_NOTFOUND: + if ( !op->o_bd->syncinfo ) { + snprintf( gid, sizeof( gid ), "%s-%08lx-%08lx", + bdb_uuid.bv_val, (long) op->o_connid, (long) op->o_opid ); + + slap_get_csn( op, csnbuf, sizeof(csnbuf), &csn, 1 ); + + if ( 0 ) { +txn_retry: + rs->sr_err = TXN_ABORT( ltid ); + if ( rs->sr_err != 0 ) { + rs->sr_err = LDAP_OTHER; + return rs->sr_err; + } + + bdb_trans_backoff( ++num_retries ); + ldap_pvt_thread_yield(); + } + rs->sr_err = TXN_BEGIN( bdb->bi_dbenv, NULL, <id, bdb->bi_db_opflags ); + if ( rs->sr_err != 0 ) { + rs->sr_err = LDAP_OTHER; + return rs->sr_err; + } + + rs->sr_err = bdb_csn_commit( op, rs, ltid, NULL, &suffix_ei, + &ctxcsn_e, &ctxcsn_added, locker ); + switch( rs->sr_err ) { + case BDB_CSN_ABORT: + LOCK_ID_FREE( bdb->bi_dbenv, locker ); + return LDAP_OTHER; + case BDB_CSN_RETRY: + goto txn_retry; + } + + rs->sr_err = TXN_PREPARE( ltid, gid ); + if ( rs->sr_err != 0 ) { + rs->sr_err = LDAP_OTHER; + return rs->sr_err; + } + + bdb_cache_add( bdb, suffix_ei, ctxcsn_e, &ctx_nrdn, locker ); + + rs->sr_err = TXN_COMMIT( ltid, 0 ); + if ( rs->sr_err != 0 ) { + rs->sr_err = LDAP_OTHER; + return rs->sr_err; + } + + ctxcsn_ei = NULL; + rs->sr_err = bdb_dn2entry( op, NULL, &ctxcsn_ndn, &ctxcsn_ei, + 0, locker, ctxcsn_lock ); + ch_free( ctxcsn_ndn.bv_val ); + + if ( ctxcsn_ei ) { + ctxcsn_e = ctxcsn_ei->bei_e; + } + } else { + LOCK_ID_FREE( bdb->bi_dbenv, locker ); + return LDAP_OTHER; + } + break; + + default: + LOCK_ID_FREE (bdb->bi_dbenv, locker ); + return LDAP_OTHER; + } + + if ( ctxcsn_e ) { + if ( op->o_bd->syncinfo ) { + csn_a = attr_find( ctxcsn_e->e_attrs, slap_schema.si_ad_syncreplCookie ); + } else { + csn_a = attr_find( ctxcsn_e->e_attrs, slap_schema.si_ad_contextCSN ); + } + if ( csn_a ) { + *search_context_csn = ber_dupbv( NULL, &csn_a->a_vals[0] ); + } else { + *search_context_csn = NULL; + } + } else { + *search_context_csn = NULL; + } + } + + return LDAP_SUCCESS; +} diff --git a/servers/slapd/back-bdb/proto-bdb.h b/servers/slapd/back-bdb/proto-bdb.h index 8336beb4a9..58f1d92dc4 100644 --- a/servers/slapd/back-bdb/proto-bdb.h +++ b/servers/slapd/back-bdb/proto-bdb.h @@ -37,11 +37,16 @@ void bdb_attr_index_destroy LDAP_P(( Avlnode *tree )); * ctxcsn.c */ #define bdb_csn_commit BDB_SYMBOL(csn_commit) +#define bdb_get_commit_csn BDB_SYMBOL(get_commit_csn) int bdb_csn_commit LDAP_P(( Operation *op, SlapReply *rs, DB_TXN *tid, EntryInfo *ei, EntryInfo **suffix_ei, Entry **ctxcsn_e, int *ctxcsn_added, u_int32_t locker )); +int bdb_get_commit_csn LDAP_P(( Operation *op, SlapReply *rs, + struct berval **search_context_csn, + u_int32_t locker, DB_LOCK *ctxcsn_lock )); + /* * dbcache.c */ diff --git a/servers/slapd/back-bdb/search.c b/servers/slapd/back-bdb/search.c index 5125c921f4..2e5d868c83 100644 --- a/servers/slapd/back-bdb/search.c +++ b/servers/slapd/back-bdb/search.c @@ -320,12 +320,6 @@ bdb_cancel( Operation *op, SlapReply *rs ) ps_list->o_cancel = SLAP_CANCEL_DONE; LDAP_LIST_REMOVE( ps_list, o_ps_link ); -#if 0 - bdb_build_sync_done_ctrl( conn, ps_list, ps_list->ctrls, - 1, &latest_entrycsn_bv ); - send_ldap_result( conn, ps_list, LDAP_CANCELLED, - NULL, NULL, NULL, ps_list->ctrls, ps_list->nentries); -#endif rs->sr_err = LDAP_CANCELLED; send_ldap_result( ps_list, rs ); @@ -372,15 +366,7 @@ bdb_do_search( Operation *op, SlapReply *rs, Operation *sop, AttributeAssertion aa_ge, aa_eq, aa_le; int entry_count = 0; struct berval *search_context_csn = NULL; - struct berval ctxcsn_rdn = { 0, NULL }; - struct berval ctxcsn_ndn = { 0, NULL }; - EntryInfo *ctxcsn_ei; - Entry *ctxcsn_e; DB_LOCK ctxcsn_lock; - Attribute *csn_a; -#if 0 - struct berval entrycsn_bv = { 0, NULL }; -#endif LDAPControl *ctrls[SLAP_SEARCH_MAX_CTRLS]; int num_ctrls = 0; AttributeName uuid_attr[2]; @@ -661,59 +647,11 @@ dn2entry_retry: } e = NULL; - if ( sop->o_sync_mode != SLAP_SYNC_NONE ) { - if ( sop->o_bd->syncinfo ) { - char substr[67]; - sprintf( substr, "cn=syncrepl%d", sop->o_bd->syncinfo->id ); - ber_str2bv( substr, strlen( substr ), 0, &ctxcsn_rdn ); - build_new_dn( &ctxcsn_ndn, &op->o_bd->be_nsuffix[0], &ctxcsn_rdn ); - } else { - ber_str2bv( "cn=ldapsync", strlen("cn=ldapsync"), 0, &ctxcsn_rdn ); - build_new_dn( &ctxcsn_ndn, &op->o_bd->be_nsuffix[0], &ctxcsn_rdn ); - } - -ctxcsn_retry : - rs->sr_err = bdb_dn2entry( op, NULL, &ctxcsn_ndn, &ctxcsn_ei, 0, locker, &ctxcsn_lock ); - ch_free( ctxcsn_ndn.bv_val ); - - switch(rs->sr_err) { - case 0: - e = ei->bei_e; break; - case LDAP_BUSY: - send_ldap_error( sop, rs, LDAP_BUSY, "ldap server busy" ); - LOCK_ID_FREE (bdb->bi_dbenv, locker ); - return LDAP_BUSY; - case DB_LOCK_DEADLOCK: - case DB_LOCK_NOTGRANTED: - goto ctxcsn_retry; - case DB_NOTFOUND: - send_ldap_error( sop, rs, LDAP_OTHER, "context csn entry not present" ); - LOCK_ID_FREE( bdb->bi_dbenv, locker ); - return rs->sr_err; - default: - send_ldap_error( sop, rs, LDAP_OTHER, "internal error" ); - LOCK_ID_FREE (bdb->bi_dbenv, locker ); - return rs->sr_err; - } - - if ( ctxcsn_ei ) { - ctxcsn_e = ctxcsn_ei->bei_e; - } + rs->sr_err = bdb_get_commit_csn( sop, rs, &search_context_csn, locker, &ctxcsn_lock ); - if ( ctxcsn_e ) { - if ( sop->o_bd->syncinfo ) { - csn_a = attr_find( ctxcsn_e->e_attrs, slap_schema.si_ad_syncreplCookie ); - } else { - csn_a = attr_find( ctxcsn_e->e_attrs, slap_schema.si_ad_contextCSN ); - } - if ( csn_a ) { - search_context_csn = ber_dupbv( NULL, &csn_a->a_vals[0] ); - } else { - search_context_csn = NULL; - } - } else { - search_context_csn = NULL; - } + if ( rs->sr_err != LDAP_SUCCESS ) { + send_ldap_error( sop, rs, rs->sr_err, "error in csn management in search" ); + goto done; } /* select candidates */