From fe3b6d00714d551a4c781ee24627e2586d06459f Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Sun, 5 Feb 2006 01:09:48 +0000 Subject: [PATCH] ITS#4384 rework entryCSN handling, retrieve from incoming request if it was provided. Always check and graduate, regardless of shadow status. --- servers/slapd/add.c | 24 ++++++---- servers/slapd/back-bdb/add.c | 3 +- servers/slapd/back-bdb/delete.c | 5 +- servers/slapd/back-bdb/modify.c | 7 ++- servers/slapd/back-bdb/modrdn.c | 5 +- servers/slapd/back-ldbm/delete.c | 5 +- servers/slapd/back-ldbm/modify.c | 6 +-- servers/slapd/back-ldbm/modrdn.c | 4 +- servers/slapd/back-ldif/ldif.c | 17 ++++--- servers/slapd/back-sql/add.c | 1 + servers/slapd/back-sql/modify.c | 1 + servers/slapd/back-sql/modrdn.c | 3 ++ servers/slapd/modify.c | 80 +++++++++++++++++--------------- servers/slapd/modrdn.c | 7 --- 14 files changed, 86 insertions(+), 82 deletions(-) diff --git a/servers/slapd/add.c b/servers/slapd/add.c index 0f3f09a7ed..bca76664dd 100644 --- a/servers/slapd/add.c +++ b/servers/slapd/add.c @@ -654,12 +654,22 @@ int slap_add_opattrs( if ( SLAP_LASTMOD( op->o_bd ) ) { char *ptr; timestamp.bv_val = timebuf; + int gotcsn = 0; + + a = attr_find( op->ora_e->e_attrs, slap_schema.si_ad_entryCSN ); + if ( a ) { + gotcsn = 1; + csn = a->a_vals[0]; + } if ( BER_BVISEMPTY( &op->o_csn )) { - if ( SLAP_SHADOW( op->o_bd )) - manage_ctxcsn = 0; - csn.bv_val = csnbuf; - csn.bv_len = sizeof(csnbuf); - slap_get_csn( op, &csn, manage_ctxcsn ); + if ( !gotcsn ) { + csn.bv_val = csnbuf; + csn.bv_len = sizeof(csnbuf); + slap_get_csn( op, &csn, manage_ctxcsn ); + } else { + if ( manage_ctxcsn ) + slap_queue_csn( op, &csn ); + } } else { csn = op->o_csn; } @@ -712,9 +722,7 @@ int slap_add_opattrs( slap_schema.si_ad_createTimestamp, ×tamp, NULL ); } - a = attr_find( op->ora_e->e_attrs, - slap_schema.si_ad_entryCSN ); - if ( !a ) { + if ( !gotcsn ) { attr_merge_one( op->ora_e, slap_schema.si_ad_entryCSN, &csn, NULL ); } diff --git a/servers/slapd/back-bdb/add.c b/servers/slapd/back-bdb/add.c index ef2c6dfc29..cd37908a20 100644 --- a/servers/slapd/back-bdb/add.c +++ b/servers/slapd/back-bdb/add.c @@ -410,8 +410,7 @@ retry: /* transaction retry */ return_results: send_ldap_result( op, rs ); - if ( !SLAP_SHADOW( op->o_bd )) - slap_graduate_commit_csn( op ); + slap_graduate_commit_csn( op ); if( ltid != NULL ) { TXN_ABORT( ltid ); diff --git a/servers/slapd/back-bdb/delete.c b/servers/slapd/back-bdb/delete.c index 3c5e7e9ba5..02038dc55c 100644 --- a/servers/slapd/back-bdb/delete.c +++ b/servers/slapd/back-bdb/delete.c @@ -58,7 +58,7 @@ bdb_delete( Operation *op, SlapReply *rs ) op->o_req_dn.bv_val, 0, 0 ); /* allocate CSN */ - if ( !SLAP_SHADOW( op->o_bd )) { + if ( BER_BVISEMPTY( &op->o_csn )) { struct berval csn; char csnbuf[LDAP_LUTIL_CSNSTR_BUFSIZE]; @@ -527,8 +527,7 @@ return_results: op->o_private = NULL; send_ldap_result( op, rs ); - if ( !SLAP_SHADOW( op->o_bd )) - slap_graduate_commit_csn( op ); + slap_graduate_commit_csn( op ); if( preread_ctrl != NULL ) { slap_sl_free( (*preread_ctrl)->ldctl_value.bv_val, op->o_tmpmemctx ); diff --git a/servers/slapd/back-bdb/modify.c b/servers/slapd/back-bdb/modify.c index 317a1797d1..21faa993e6 100644 --- a/servers/slapd/back-bdb/modify.c +++ b/servers/slapd/back-bdb/modify.c @@ -298,8 +298,7 @@ bdb_modify( Operation *op, SlapReply *rs ) ctrls[num_ctrls] = NULL; - if ( !SLAP_SHADOW( op->o_bd )) - slap_mods_opattrs( op, &op->orm_modlist, 1 ); + slap_mods_opattrs( op, &op->orm_modlist, 1 ); if( 0 ) { retry: /* transaction retry */ @@ -590,8 +589,6 @@ return_results: attrs_free( dummy.e_attrs ); } send_ldap_result( op, rs ); - if ( !SLAP_SHADOW( op->o_bd )) - slap_graduate_commit_csn( op ); if( rs->sr_err == LDAP_SUCCESS && bdb->bi_txn_cp ) { TXN_CHECKPOINT( bdb->bi_dbenv, @@ -599,6 +596,8 @@ return_results: } done: + slap_graduate_commit_csn( op ); + if( ltid != NULL ) { TXN_ABORT( ltid ); } diff --git a/servers/slapd/back-bdb/modrdn.c b/servers/slapd/back-bdb/modrdn.c index 21d06d728b..cc0ffcb476 100644 --- a/servers/slapd/back-bdb/modrdn.c +++ b/servers/slapd/back-bdb/modrdn.c @@ -67,8 +67,7 @@ bdb_modrdn( Operation *op, SlapReply *rs ) op->o_req_dn.bv_val,op->oq_modrdn.rs_newrdn.bv_val, op->oq_modrdn.rs_newSup ? op->oq_modrdn.rs_newSup->bv_val : "NULL" ); - if ( !SLAP_SHADOW( op->o_bd )) - slap_mods_opattrs( op, &op->orr_modlist, 1 ); + slap_mods_opattrs( op, &op->orr_modlist, 1 ); if( 0 ) { retry: /* transaction retry */ @@ -744,6 +743,8 @@ return_results: } done: + slap_graduate_commit_csn( op ); + if( new_dn.bv_val != NULL ) free( new_dn.bv_val ); if( new_ndn.bv_val != NULL ) free( new_ndn.bv_val ); diff --git a/servers/slapd/back-ldbm/delete.c b/servers/slapd/back-ldbm/delete.c index 00372aa029..ec623e6253 100644 --- a/servers/slapd/back-ldbm/delete.c +++ b/servers/slapd/back-ldbm/delete.c @@ -46,7 +46,7 @@ ldbm_back_delete( ldap_pvt_thread_rdwr_wlock(&li->li_giant_rwlock); /* allocate CSN */ - if ( !SLAP_SHADOW( op->o_bd )) { + if ( BER_BVISEMPTY( &op->o_csn )) { struct berval csn; char csnbuf[LDAP_LUTIL_CSNSTR_BUFSIZE]; @@ -217,8 +217,7 @@ return_results:; ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock); send_ldap_result( op, rs ); - if ( !SLAP_SHADOW( op->o_bd )) - slap_graduate_commit_csn( op ); + slap_graduate_commit_csn( op ); return rc; } diff --git a/servers/slapd/back-ldbm/modify.c b/servers/slapd/back-ldbm/modify.c index 191365ba19..9625682841 100644 --- a/servers/slapd/back-ldbm/modify.c +++ b/servers/slapd/back-ldbm/modify.c @@ -241,8 +241,7 @@ ldbm_back_modify( Debug(LDAP_DEBUG_ARGS, "ldbm_back_modify:\n", 0, 0, 0); - if ( !SLAP_SHADOW( op->o_bd )) - slap_mods_opattrs( op, &op->orm_modlist, 1 ); + slap_mods_opattrs( op, &op->orm_modlist, 1 ); /* grab giant lock for writing */ ldap_pvt_thread_rdwr_wlock(&li->li_giant_rwlock); @@ -300,8 +299,7 @@ return_results:; ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock); send_ldap_result( op, rs ); - if ( !SLAP_SHADOW( op->o_bd )) - slap_graduate_commit_csn( op ); + slap_graduate_commit_csn( op ); rs->sr_text = NULL; return rs->sr_err; diff --git a/servers/slapd/back-ldbm/modrdn.c b/servers/slapd/back-ldbm/modrdn.c index 668939f9b8..4ed808c339 100644 --- a/servers/slapd/back-ldbm/modrdn.c +++ b/servers/slapd/back-ldbm/modrdn.c @@ -64,8 +64,7 @@ ldbm_back_modrdn( ( op->oq_modrdn.rs_newSup && op->oq_modrdn.rs_newSup->bv_len ) ? op->oq_modrdn.rs_newSup->bv_val : "NULL", 0 ); - if ( !SLAP_SHADOW( op->o_bd )) - slap_mods_opattrs( op, &op->orr_modlist, 1 ); + slap_mods_opattrs( op, &op->orr_modlist, 1 ); /* grab giant lock for writing */ ldap_pvt_thread_rdwr_wlock(&li->li_giant_rwlock); @@ -422,6 +421,7 @@ ldbm_back_modrdn( cache_entry_commit( e ); return_results: + slap_graduate_commit_csn( op ); if( new_dn.bv_val != NULL ) free( new_dn.bv_val ); if( new_ndn.bv_val != NULL ) free( new_ndn.bv_val ); if( old_ndn.bv_val != NULL ) free( old_ndn.bv_val ); diff --git a/servers/slapd/back-ldif/ldif.c b/servers/slapd/back-ldif/ldif.c index d046b26695..8293c52fa1 100644 --- a/servers/slapd/back-ldif/ldif.c +++ b/servers/slapd/back-ldif/ldif.c @@ -819,8 +819,7 @@ static int ldif_back_add(Operation *op, SlapReply *rs) { send_res: send_ldap_result(op, rs); - if ( !SLAP_SHADOW( op->o_bd )) - slap_graduate_commit_csn( op ); + slap_graduate_commit_csn( op ); return 0; } @@ -831,8 +830,7 @@ static int ldif_back_modify(Operation *op, SlapReply *rs) { Entry * entry = NULL; int spew_res; - if ( !SLAP_SHADOW( op->o_bd )) - slap_mods_opattrs( op, &op->orm_modlist, 1 ); + slap_mods_opattrs( op, &op->orm_modlist, 1 ); ldap_pvt_thread_mutex_lock(&ni->li_mutex); dn2path(&op->o_req_ndn, &op->o_bd->be_nsuffix[0], &ni->li_base_path, @@ -866,8 +864,7 @@ static int ldif_back_modify(Operation *op, SlapReply *rs) { rs->sr_text = NULL; ldap_pvt_thread_mutex_unlock(&ni->li_mutex); send_ldap_result(op, rs); - if ( !SLAP_SHADOW( op->o_bd )) - slap_graduate_commit_csn( op ); + slap_graduate_commit_csn( op ); return 0; } @@ -876,7 +873,7 @@ static int ldif_back_delete(Operation *op, SlapReply *rs) { struct berval path = BER_BVNULL; int res = 0; - if ( !SLAP_SHADOW( op->o_bd )) { + if ( BER_BVISEMPTY( &op->o_csn )) { struct berval csn; char csnbuf[LDAP_LUTIL_CSNSTR_BUFSIZE]; @@ -909,8 +906,7 @@ static int ldif_back_delete(Operation *op, SlapReply *rs) { SLAP_FREE(path.bv_val); ldap_pvt_thread_mutex_unlock(&ni->li_mutex); send_ldap_result(op, rs); - if ( !SLAP_SHADOW( op->o_bd )) - slap_graduate_commit_csn( op ); + slap_graduate_commit_csn( op ); return 0; } @@ -975,6 +971,8 @@ ldif_back_modrdn(Operation *op, SlapReply *rs) Entry * entry = NULL; int res; + slap_mods_opattrs( op, &op->orr_modlist, 1 ); + ldap_pvt_thread_mutex_lock( &ni->li_mutex ); ldap_pvt_thread_mutex_lock( &entry2str_mutex ); entry = (Entry *) get_entry( op, &ni->li_base_path ); @@ -1018,6 +1016,7 @@ ldif_back_modrdn(Operation *op, SlapReply *rs) ldap_pvt_thread_mutex_unlock( &ni->li_mutex ); ldap_pvt_thread_mutex_unlock( &entry2str_mutex ); send_ldap_result( op, rs ); + slap_graduate_commit_csn( op ); return 0; } diff --git a/servers/slapd/back-sql/add.c b/servers/slapd/back-sql/add.c index c09b148d1e..a850858bf5 100644 --- a/servers/slapd/back-sql/add.c +++ b/servers/slapd/back-sql/add.c @@ -1506,6 +1506,7 @@ done:; #endif /* SLAP_ACL_HONOR_DISCLOSE */ send_ldap_result( op, rs ); + slap_graduate_commit_csn( op ); if ( !BER_BVISNULL( &realdn ) && realdn.bv_val != op->ora_e->e_name.bv_val ) diff --git a/servers/slapd/back-sql/modify.c b/servers/slapd/back-sql/modify.c index a40f58d48f..c6c84b0c02 100644 --- a/servers/slapd/back-sql/modify.c +++ b/servers/slapd/back-sql/modify.c @@ -191,6 +191,7 @@ done:; #endif /* SLAP_ACL_HONOR_DISCLOSE */ send_ldap_result( op, rs ); + slap_graduate_commit_csn( op ); if ( !BER_BVISNULL( &bsi.bsi_base_id.eid_ndn ) ) { (void)backsql_free_entryID( op, &bsi.bsi_base_id, 0 ); diff --git a/servers/slapd/back-sql/modrdn.c b/servers/slapd/back-sql/modrdn.c index cbfeb60dcc..756f99798c 100644 --- a/servers/slapd/back-sql/modrdn.c +++ b/servers/slapd/back-sql/modrdn.c @@ -394,6 +394,8 @@ backsql_modrdn( Operation *op, SlapReply *rs ) assert( op->orr_modlist != NULL ); + slap_mods_opattrs( op, &op->orr_modlist, 1 ); + oc = backsql_id2oc( bi, e_id.eid_oc_id ); rs->sr_err = backsql_modify_internal( op, rs, dbh, oc, &e_id, op->orr_modlist ); slap_graduate_commit_csn( op ); @@ -492,6 +494,7 @@ done:; } send_ldap_result( op, rs ); + slap_graduate_commit_csn( op ); if ( !BER_BVISNULL( &realnew_dn ) && realnew_dn.bv_val != new_dn.bv_val ) { ch_free( realnew_dn.bv_val ); diff --git a/servers/slapd/modify.c b/servers/slapd/modify.c index 44f67247c7..b044c059fc 100644 --- a/servers/slapd/modify.c +++ b/servers/slapd/modify.c @@ -809,7 +809,8 @@ void slap_timestamp( time_t *tm, struct berval *bv ) #endif } -/* modify only calls this for non-replicas. modrdn always calls. +/* Called for all modify and modrdn ops. If the current op was replicated + * from elsewhere, all of the attrs should already be present. */ void slap_mods_opattrs( Operation *op, @@ -821,14 +822,34 @@ void slap_mods_opattrs( char timebuf[ LDAP_LUTIL_GENTIME_BUFSIZE ]; char csnbuf[ LDAP_LUTIL_CSNSTR_BUFSIZE ]; Modifications *mod, **modtail, *modlast; + int gotcsn = 0, gotmname = 0, gotmtime = 0; if ( SLAP_LASTMOD( op->o_bd ) ) { char *ptr; timestamp.bv_val = timebuf; + for ( modtail = modsp; *modtail; modtail = &(*modtail)->sml_next ) { + if ( (*modtail)->sml_op != LDAP_MOD_ADD && + (*modtail)->sml_op != LDAP_MOD_REPLACE ) continue; + if ( (*modtail)->sml_desc == slap_schema.si_ad_entryCSN ) { + csn = (*modtail)->sml_values[0]; + gotcsn = 1; + } else + if ( (*modtail)->sml_desc == slap_schema.si_ad_modifiersName ) { + gotmname = 1; + } else + if ( (*modtail)->sml_desc == slap_schema.si_ad_modifyTimestamp ) { + gotmtime = 1; + } + } if ( BER_BVISEMPTY( &op->o_csn )) { - csn.bv_val = csnbuf; - csn.bv_len = sizeof( csnbuf ); - slap_get_csn( op, &csn, manage_ctxcsn ); + if ( !gotcsn ) { + csn.bv_val = csnbuf; + csn.bv_len = sizeof( csnbuf ); + slap_get_csn( op, &csn, manage_ctxcsn ); + } else { + if ( manage_ctxcsn ) + slap_queue_csn( op, &csn ); + } } else { csn = op->o_csn; } @@ -855,33 +876,24 @@ void slap_mods_opattrs( nname = op->o_ndn; } - for ( modtail = modsp; *modtail; modtail = &(*modtail)->sml_next ) - ; - - mod = (Modifications *) ch_malloc( sizeof( Modifications ) ); - mod->sml_op = LDAP_MOD_REPLACE; - mod->sml_flags = SLAP_MOD_INTERNAL; - mod->sml_next = NULL; - BER_BVZERO( &mod->sml_type ); - mod->sml_desc = slap_schema.si_ad_entryCSN; - mod->sml_values = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) ); - ber_dupbv( &mod->sml_values[0], &csn ); - BER_BVZERO( &mod->sml_values[1] ); - assert( !BER_BVISNULL( &mod->sml_values[0] ) ); - mod->sml_nvalues = NULL; - *modtail = mod; - modlast = mod; - modtail = &mod->sml_next; - - if ( get_manageDIT( op ) ) { - for ( mod = *modsp; mod != modlast; mod = mod->sml_next ) { - if ( mod->sml_desc == slap_schema.si_ad_modifiersName ) { - break; - } - } + if ( !gotcsn ) { + mod = (Modifications *) ch_malloc( sizeof( Modifications ) ); + mod->sml_op = LDAP_MOD_REPLACE; + mod->sml_flags = SLAP_MOD_INTERNAL; + mod->sml_next = NULL; + BER_BVZERO( &mod->sml_type ); + mod->sml_desc = slap_schema.si_ad_entryCSN; + mod->sml_values = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) ); + ber_dupbv( &mod->sml_values[0], &csn ); + BER_BVZERO( &mod->sml_values[1] ); + assert( !BER_BVISNULL( &mod->sml_values[0] ) ); + mod->sml_nvalues = NULL; + *modtail = mod; + modlast = mod; + modtail = &mod->sml_next; } - if ( mod->sml_desc != slap_schema.si_ad_modifiersName ) { + if ( !gotmname ) { mod = (Modifications *) ch_malloc( sizeof( Modifications ) ); mod->sml_op = LDAP_MOD_REPLACE; mod->sml_flags = SLAP_MOD_INTERNAL; @@ -901,15 +913,7 @@ void slap_mods_opattrs( modtail = &mod->sml_next; } - if ( get_manageDIT( op ) ) { - for ( mod = *modsp; mod != modlast; mod = mod->sml_next ) { - if ( mod->sml_desc == slap_schema.si_ad_modifyTimestamp ) { - break; - } - } - } - - if ( mod->sml_desc != slap_schema.si_ad_modifyTimestamp ) { + if ( !gotmtime ) { mod = (Modifications *) ch_malloc( sizeof( Modifications ) ); mod->sml_op = LDAP_MOD_REPLACE; mod->sml_flags = SLAP_MOD_INTERNAL; diff --git a/servers/slapd/modrdn.c b/servers/slapd/modrdn.c index 328f49ec60..4a5cf8f9f6 100644 --- a/servers/slapd/modrdn.c +++ b/servers/slapd/modrdn.c @@ -500,13 +500,6 @@ slap_modrdn2mods( done: -#if 0 - /* should be done by backend */ - if ( rs->sr_err == LDAP_SUCCESS && !repl_user ) { - slap_mods_opattrs( op, &op->orr_modlist, 1 ); - } -#endif - /* LDAP v2 supporting correct attribute handling. */ if ( rs->sr_err != LDAP_SUCCESS && op->orr_modlist != NULL ) { Modifications *tmp; -- 2.39.5