Commit 3be0b77c authored by Jong Hyuk Choi's avatar Jong Hyuk Choi
Browse files

Context CSN Patch (2)

- BDB context csn codes moved to a separate function in back-bdb/ctxcsn.c
parent d53c90dc
......@@ -377,7 +377,7 @@ do_add( Operation *op, SlapReply *rs )
done:
#ifdef LDAP_SYNC
graduate_commit_csn( op );
slap_graduate_commit_csn( op );
#endif
if( modlist != NULL ) {
......
......@@ -6,12 +6,12 @@ SRCS = init.c tools.c config.c \
add.c bind.c compare.c delete.c modify.c modrdn.c search.c \
extended.c passwd.c referral.c operational.c \
attr.c index.c key.c dbcache.c filterindex.c \
dn2entry.c dn2id.c error.c id2entry.c idl.c nextid.c cache.c trans.c
dn2entry.c dn2id.c error.c id2entry.c idl.c nextid.c cache.c trans.c ctxcsn.c
OBJS = init.lo tools.lo config.lo \
add.lo bind.lo compare.lo delete.lo modify.lo modrdn.lo search.lo \
extended.lo passwd.lo referral.lo operational.lo \
attr.lo index.lo key.lo dbcache.lo filterindex.lo \
dn2entry.lo dn2id.lo error.lo id2entry.lo idl.lo nextid.lo cache.lo trans.lo
dn2entry.lo dn2id.lo error.lo id2entry.lo idl.lo nextid.lo cache.lo trans.lo ctxcsn.lo
LDAP_INCDIR= ../../../include
LDAP_LIBDIR= ../../../libraries
......
......@@ -37,17 +37,10 @@ bdb_add(Operation *op, SlapReply *rs )
#ifdef LDAP_SYNC
Operation* ps_list;
struct berval *max_committed_csn = NULL;
EntryInfo *suffix_ei = NULL;
EntryInfo *ctxcsn_ei = NULL;
Entry *ctxcsn_e = NULL;
DB_LOCK suffix_lock;
DB_LOCK ctxcsn_lock;
struct berval ctxcsn_rdn = { 0, NULL };
struct berval ctxcsn_ndn = { 0, NULL };
int rc, ret;
int ctxcsn_added = 0;
ID ctxcsn_id;
int rc;
EntryInfo *suffix_ei;
Entry *ctxcsn_e;
int ctxcsn_added = 0;
#endif
#ifdef NEW_LOGGING
......@@ -92,24 +85,6 @@ bdb_add(Operation *op, SlapReply *rs )
goto return_results;
}
#ifdef LDAP_SYNC
if ( be_issuffix( op->o_bd, &op->oq_add.rs_e->e_nname ) ) {
rs->sr_err = bdb_next_id( op->o_bd, NULL, &ctxcsn_id );
if( rs->sr_err != 0 ) {
#ifdef NEW_LOGGING
LDAP_LOG ( OPERATION, ERR,
"bdb_add: next_id failed (%d)\n", rs->sr_err, 0, 0 );
#else
Debug( LDAP_DEBUG_TRACE,
"bdb_add: next_id failed (%d)\n", rs->sr_err, 0, 0 );
#endif
rs->sr_err = LDAP_OTHER;
rs->sr_text = "internal error";
goto return_results;
}
}
#endif
if( 0 ) {
retry: /* transaction retry */
if( p ) {
......@@ -496,132 +471,13 @@ retry: /* transaction retry */
}
#ifdef LDAP_SYNC
ber_str2bv( "cn=ldapsync", strlen("cn=ldapsync"), 0, &ctxcsn_rdn );
build_new_dn( &ctxcsn_ndn, &op->o_bd->be_nsuffix[0], &ctxcsn_rdn );
rc = bdb_dn2entry( op, ltid, &ctxcsn_ndn, &ctxcsn_ei,
0, locker, &ctxcsn_lock );
if ( ctxcsn_ei ) {
ctxcsn_e = ctxcsn_ei->bei_e;
bdb_cache_entry_db_relock( bdb->bi_dbenv, locker, ctxcsn_ei, 1, 0, &ctxcsn_lock );
}
max_committed_csn = commit_csn( op );
ctxcsn_added = 0;
if ( max_committed_csn == NULL )
goto txn_end;
switch( rc ) {
case 0:
if ( !ctxcsn_e ) {
rs->sr_err = LDAP_OTHER;
rs->sr_text = "context csn not present";
goto return_results;
} else {
attr_delete( &ctxcsn_e->e_attrs, slap_schema.si_ad_contextCSN );
attr_merge_normalize_one( ctxcsn_e, slap_schema.si_ad_contextCSN,
max_committed_csn, NULL );
ret = bdb_id2entry_update( op->o_bd, ltid, ctxcsn_e );
switch ( ret ) {
case 0 :
break;
case DB_LOCK_DEADLOCK :
case DB_LOCK_NOTGRANTED :
goto rewind;
default :
rs->sr_err = ret;
rs->sr_text = "context csn update failed";
goto return_results;
}
ret = bdb_index_entry_add( op, ltid, ctxcsn_e );
switch ( ret ) {
case 0 :
break;
case DB_LOCK_DEADLOCK :
case DB_LOCK_NOTGRANTED :
goto rewind;
default :
rs->sr_err = LDAP_OTHER;
rs->sr_text = "context csn indexing failed";
goto return_results;
}
}
break;
case DB_NOTFOUND:
if ( !be_issuffix( op->o_bd, &op->ora_e->e_nname ) ) {
rc = bdb_dn2entry( op, ltid, &op->o_bd->be_nsuffix[0], &suffix_ei,
0, locker, &suffix_lock );
} else {
suffix_ei = ei;
}
ctxcsn_e = create_context_csn_entry( op->o_bd, max_committed_csn );
ctxcsn_e->e_id = ctxcsn_id;
ctxcsn_added = 1;
ret = bdb_dn2id_add( op, ltid, suffix_ei, ctxcsn_e );
switch ( ret ) {
case 0 :
break;
case DB_LOCK_DEADLOCK :
case DB_LOCK_NOTGRANTED :
goto rewind;
case DB_KEYEXIST :
rs->sr_err = LDAP_OTHER;
rs->sr_text = "context csn exists before contex prefix does";
goto return_results;
default :
rs->sr_err = LDAP_OTHER;
rs->sr_text = "context csn store failed";
goto return_results;
}
ret = bdb_id2entry_add( op->o_bd, ltid, ctxcsn_e );
switch ( ret ) {
case 0 :
break;
case DB_LOCK_DEADLOCK :
case DB_LOCK_NOTGRANTED :
goto rewind;
default :
rs->sr_err = LDAP_OTHER;
rs->sr_text = "context csn store failed";
goto return_results;
}
ret = bdb_index_entry_add( op, ltid, ctxcsn_e );
switch ( ret ) {
case 0 :
break;
case DB_LOCK_DEADLOCK :
case DB_LOCK_NOTGRANTED :
goto rewind;
default :
rs->sr_err = LDAP_OTHER;
rs->sr_text = "context csn indexing failed";
goto return_results;
}
break;
case DB_LOCK_DEADLOCK:
case DB_LOCK_NOTGRANTED:
goto rewind;
case LDAP_BUSY:
rs->sr_err = rc;
rs->sr_text = "ldap server busy";
goto return_results;
default:
rs->sr_err = LDAP_OTHER;
rs->sr_text = "internal error";
rc = bdb_csn_commit( op, rs, ltid, ei, &suffix_ei, &ctxcsn_e, &ctxcsn_added, locker );
switch ( rc ) {
case BDB_CSN_ABORT :
goto return_results;
case BDB_CSN_RETRY :
goto retry;
}
goto txn_end;
rewind :
rewind_commit_csn( op );
goto retry;
txn_end:
#endif
if ( op->o_noop ) {
......
......@@ -223,6 +223,12 @@ struct bdb_op_info {
#define BDB_REUSE_LOCKERS
#ifdef LDAP_SYNC
#define BDB_CSN_COMMIT 0
#define BDB_CSN_ABORT 1
#define BDB_CSN_RETRY 2
#endif
LDAP_END_DECL
#include "proto-bdb.h"
......
/* $OpenLDAP$ */
/*
* back-bdb Context CSN Management Routines
*/
/* Copyright (c) 2003 by International Business Machines, Inc.
*
* International Business Machines, Inc. (hereinafter called IBM) grants
* permission under its copyrights to use, copy, modify, and distribute this
* Software with or without fee, provided that the above copyright notice and
* all paragraphs of this notice appear in all copies, and that the name of IBM
* not be used in connection with the marketing of any product incorporating
* the Software or modifications thereof, without specific, written prior
* permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
* DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
* IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
*/
#include "portable.h"
#include <stdio.h>
#include <ac/string.h>
#include <ac/time.h>
#include "back-bdb.h"
#include "external.h"
#ifdef LDAP_SYNC
int
bdb_csn_commit(
Operation *op,
SlapReply *rs,
DB_TXN *tid,
EntryInfo *ei,
EntryInfo **suffix_ei,
Entry **ctxcsn_e,
int *ctxcsn_added,
u_int32_t locker
)
{
struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
struct berval ctxcsn_rdn = { 0, NULL };
struct berval ctxcsn_ndn = { 0, NULL };
EntryInfo *ctxcsn_ei = NULL;
DB_LOCK ctxcsn_lock;
struct berval *max_committed_csn = NULL;
DB_LOCK suffix_lock;
int rc, ret;
ID ctxcsn_id;
ber_str2bv( "cn=ldapsync", strlen("cn=ldapsync"), 0, &ctxcsn_rdn );
build_new_dn( &ctxcsn_ndn, &op->o_bd->be_nsuffix[0], &ctxcsn_rdn );
rc = bdb_dn2entry( op, tid, &ctxcsn_ndn, &ctxcsn_ei,
0, locker, &ctxcsn_lock );
if ( ctxcsn_ei ) {
*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 )
return BDB_CSN_COMMIT;
*ctxcsn_added = 0;
switch( rc ) {
case 0:
if ( !*ctxcsn_e ) {
rs->sr_err = LDAP_OTHER;
rs->sr_text = "context csn not present";
return BDB_CSN_ABORT;
} else {
attr_delete( &(*ctxcsn_e)->e_attrs, slap_schema.si_ad_contextCSN );
attr_merge_normalize_one( *ctxcsn_e, slap_schema.si_ad_contextCSN,
max_committed_csn, NULL );
ret = bdb_id2entry_update( op->o_bd, tid, *ctxcsn_e );
switch ( ret ) {
case 0 :
break;
case DB_LOCK_DEADLOCK :
case DB_LOCK_NOTGRANTED :
goto rewind;
default :
rs->sr_err = ret;
rs->sr_text = "context csn update failed";
return BDB_CSN_ABORT;
}
ret = bdb_index_entry_add( op, tid, *ctxcsn_e );
switch ( ret ) {
case 0 :
break;
case DB_LOCK_DEADLOCK :
case DB_LOCK_NOTGRANTED :
goto rewind;
default :
rs->sr_err = LDAP_OTHER;
rs->sr_text = "context csn indexing failed";
return BDB_CSN_ABORT;
}
}
break;
case DB_NOTFOUND:
if ( !be_issuffix( op->o_bd, &op->ora_e->e_nname ) ) {
rc = bdb_dn2entry( op, tid, &op->o_bd->be_nsuffix[0], suffix_ei,
0, locker, &suffix_lock );
} else {
*suffix_ei = ei;
}
/* This serializes add. But this case is very rare : only once. */
rs->sr_err = bdb_next_id( op->o_bd, NULL, &ctxcsn_id );
if ( rs->sr_err != 0 ) {
#ifdef NEW_LOGGING
LDAP_LOG ( OPERATION, ERR,
"bdb_add: next_id failed (%d)\n", rs->sr_err, 0, 0 );
#else
Debug( LDAP_DEBUG_TRACE,
"bdb_add: next_id failed (%d)\n", rs->sr_err, 0, 0 );
#endif
rs->sr_err = LDAP_OTHER;
rs->sr_text = "internal error";
return BDB_CSN_ABORT;
}
*ctxcsn_e = slap_create_context_csn_entry( op->o_bd, max_committed_csn );
(*ctxcsn_e)->e_id = ctxcsn_id;
*ctxcsn_added = 1;
ret = bdb_dn2id_add( op, tid, *suffix_ei, *ctxcsn_e );
switch ( ret ) {
case 0 :
break;
case DB_LOCK_DEADLOCK :
case DB_LOCK_NOTGRANTED :
goto rewind;
case DB_KEYEXIST :
rs->sr_err = LDAP_OTHER;
rs->sr_text = "context csn exists before contex prefix does";
return BDB_CSN_ABORT;
default :
rs->sr_err = LDAP_OTHER;
rs->sr_text = "context csn store failed";
return BDB_CSN_ABORT;
}
ret = bdb_id2entry_add( op->o_bd, tid, *ctxcsn_e );
switch ( ret ) {
case 0 :
break;
case DB_LOCK_DEADLOCK :
case DB_LOCK_NOTGRANTED :
goto rewind;
default :
rs->sr_err = LDAP_OTHER;
rs->sr_text = "context csn store failed";
return BDB_CSN_ABORT;
}
ret = bdb_index_entry_add( op, tid, *ctxcsn_e );
switch ( ret ) {
case 0 :
break;
case DB_LOCK_DEADLOCK :
case DB_LOCK_NOTGRANTED :
goto rewind;
default :
rs->sr_err = LDAP_OTHER;
rs->sr_text = "context csn indexing failed";
return BDB_CSN_ABORT;
}
break;
case DB_LOCK_DEADLOCK:
case DB_LOCK_NOTGRANTED:
goto rewind;
case LDAP_BUSY:
rs->sr_err = rc;
rs->sr_text = "ldap server busy";
return BDB_CSN_ABORT;
default:
rs->sr_err = LDAP_OTHER;
rs->sr_text = "internal error";
return BDB_CSN_ABORT;
}
return BDB_CSN_COMMIT;
rewind :
slap_rewind_commit_csn( op );
return BDB_CSN_RETRY;
}
#endif
......@@ -331,17 +331,10 @@ bdb_modify( Operation *op, SlapReply *rs )
#ifdef LDAP_SYNC
Operation* ps_list;
struct psid_entry *pm_list, *pm_prev;
struct berval *max_committed_csn = NULL;
EntryInfo *suffix_ei = NULL;
EntryInfo *ctxcsn_ei = NULL;
Entry *ctxcsn_e = NULL;
DB_LOCK suffix_lock;
DB_LOCK ctxcsn_lock;
struct berval ctxcsn_rdn = { 0, NULL };
struct berval ctxcsn_ndn = { 0, NULL };
int rc, ret;
int ctxcsn_added = 0;
ID ctxcsn_id;
int rc;
EntryInfo *suffix_ei;
Entry *ctxcsn_e;
int ctxcsn_added = 0;
#endif
#ifdef NEW_LOGGING
......@@ -583,147 +576,13 @@ retry: /* transaction retry */
}
#ifdef LDAP_SYNC
ber_str2bv( "cn=ldapsync", strlen("cn=ldapsync"), 0, &ctxcsn_rdn );
build_new_dn( &ctxcsn_ndn, &op->o_bd->be_nsuffix[0], &ctxcsn_rdn );
rc = bdb_dn2entry( op, ltid, &ctxcsn_ndn, &ctxcsn_ei,
0, locker, &ctxcsn_lock );
if ( ctxcsn_ei ) {
ctxcsn_e = ctxcsn_ei->bei_e;
bdb_cache_entry_db_relock( bdb->bi_dbenv, locker, ctxcsn_ei, 1, 0, &ctxcsn_lock );
}
max_committed_csn = commit_csn( op );
if ( max_committed_csn == NULL )
goto txn_end;
ctxcsn_added = 0;
switch( rc ) {
case 0:
if ( !ctxcsn_e ) {
rs->sr_err = LDAP_OTHER;
rs->sr_text = "context csn not present";
goto return_results;
} else {
attr_delete( &ctxcsn_e->e_attrs, slap_schema.si_ad_contextCSN );
attr_merge_normalize_one( ctxcsn_e, slap_schema.si_ad_contextCSN,
max_committed_csn, NULL );
ret = bdb_id2entry_update( op->o_bd, ltid, ctxcsn_e );
switch ( ret ) {
case 0 :
break;
case DB_LOCK_DEADLOCK :
case DB_LOCK_NOTGRANTED :
goto rewind;
default :
rs->sr_err = ret;
rs->sr_text = "context csn update failed";
goto return_results;
}
ret = bdb_index_entry_add( op, ltid, ctxcsn_e );
switch ( ret ) {
case 0 :
break;
case DB_LOCK_DEADLOCK :
case DB_LOCK_NOTGRANTED :
goto rewind;
default :
rs->sr_err = LDAP_OTHER;
rs->sr_text = "context csn indexing failed";
goto return_results;
}
}
break;
case DB_NOTFOUND:
if ( !be_issuffix( op->o_bd, &op->ora_e->e_nname ) ) {
rc = bdb_dn2entry( op, ltid, &op->o_bd->be_nsuffix[0], &suffix_ei,
0, locker, &suffix_lock );
} else {
suffix_ei = ei;
}
/* This serializes add. But this case is very rare : only once. */
rs->sr_err = bdb_next_id( op->o_bd, NULL, &ctxcsn_id );
if ( rs->sr_err != 0 ) {
#ifdef NEW_LOGGING
LDAP_LOG ( OPERATION, ERR,
"bdb_add: next_id failed (%d)\n", rs->sr_err, 0, 0 );
#else
Debug( LDAP_DEBUG_TRACE,
"bdb_add: next_id failed (%d)\n", rs->sr_err, 0, 0 );
#endif
rs->sr_err = LDAP_OTHER;
rs->sr_text = "internal error";
goto return_results;
}
ctxcsn_e = create_context_csn_entry( op->o_bd, max_committed_csn );
ctxcsn_e->e_id = ctxcsn_id;
ctxcsn_added = 1;
ret = bdb_dn2id_add( op, ltid, suffix_ei, ctxcsn_e );
switch ( ret ) {
case 0 :
break;
case DB_LOCK_DEADLOCK :
case DB_LOCK_NOTGRANTED :
goto rewind;
case DB_KEYEXIST :
rs->sr_err = LDAP_OTHER;
rs->sr_text = "context csn exists before contex prefix does";
goto return_results;
default :
rs->sr_err = LDAP_OTHER;
rs->sr_text = "context csn store failed";
goto return_results;
}
ret = bdb_id2entry_add( op->o_bd, ltid, ctxcsn_e );
switch ( ret ) {
case 0 :
break;
case DB_LOCK_DEADLOCK :
case DB_LOCK_NOTGRANTED :
goto rewind;
default :
rs->sr_err = LDAP_OTHER;
rs->sr_text = "context csn store failed";
goto return_results;
}
ret = bdb_index_entry_add( op, ltid, ctxcsn_e );
switch ( ret ) {
case 0 :
break;
case DB_LOCK_DEADLOCK :
case DB_LOCK_NOTGRANTED :
goto rewind;
default :
rs->sr_err = LDAP_OTHER;
rs->sr_text = "context csn indexing failed";
goto return_results;
}
break;
case DB_LOCK_DEADLOCK:
case DB_LOCK_NOTGRANTED:
goto rewind;
case LDAP_BUSY:
rs->sr_err = rc;
rs->sr_text = "ldap server busy";
goto return_results;
default:
rs->sr_err = LDAP_OTHER;
rs->sr_text = "internal error";
rc = bdb_csn_commit( op, rs, ltid, ei, &suffix_ei, &ctxcsn_e, &ctxcsn_added, locker );
switch ( rc ) {
case BDB_CSN_ABORT :
goto return_results;
case BDB_CSN_RETRY :
goto retry;
}
goto txn_end;
rewind :
rewind_commit_csn( op );
goto retry;
txn_end:
#endif
if( op->o_noop ) {
......
......@@ -33,6 +33,13 @@ int bdb_attr_index_config LDAP_P(( struct bdb_info *bdb,
void bdb_attr_index_destroy LDAP_P(( Avlnode *tree ));
/*
* ctxcsn.c
*/
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 ));
/*
* dbcache.c
*/
......
......@@ -853,11 +853,6 @@ dn2entry_retry:
} else {