From c2b339d45688060a187bf8a34c1b1c1c4699de16 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Fri, 26 Nov 2004 09:40:22 +0000 Subject: [PATCH] More syncprov fixes. test019 now passes. --- servers/slapd/ctxcsn.c | 40 +++++++++++++++++-------------- servers/slapd/overlays/syncprov.c | 24 ++++++++++++------- servers/slapd/proto-slap.h | 4 +++- servers/slapd/syncrepl.c | 9 ++++--- 4 files changed, 47 insertions(+), 30 deletions(-) diff --git a/servers/slapd/ctxcsn.c b/servers/slapd/ctxcsn.c index 8ecf113ff8..340f21db4b 100644 --- a/servers/slapd/ctxcsn.c +++ b/servers/slapd/ctxcsn.c @@ -140,6 +140,26 @@ slap_create_context_csn_entry( return e; } +void +slap_queue_csn( + Operation *op, + struct berval *csn ) +{ + struct slap_csn_entry *pending; + + pending = (struct slap_csn_entry *) ch_calloc( 1, + sizeof( struct slap_csn_entry )); + ldap_pvt_thread_mutex_lock( op->o_bd->be_pcl_mutexp ); + + pending->ce_csn = ber_dupbv( NULL, csn ); + pending->ce_connid = op->o_connid; + pending->ce_opid = op->o_opid; + pending->ce_state = SLAP_CSN_PENDING; + LDAP_TAILQ_INSERT_TAIL( op->o_bd->be_pending_csn_list, + pending, ce_csn_link ); + ldap_pvt_thread_mutex_unlock( op->o_bd->be_pcl_mutexp ); +} + int slap_get_csn( Operation *op, @@ -148,29 +168,13 @@ slap_get_csn( struct berval *csn, int manage_ctxcsn ) { - struct slap_csn_entry *pending; - if ( csn == NULL ) return LDAP_OTHER; csn->bv_len = lutil_csnstr( csnbuf, len, 0, 0 ); csn->bv_val = csnbuf; - if ( manage_ctxcsn ) { - pending = (struct slap_csn_entry *) ch_calloc( 1, - sizeof( struct slap_csn_entry )); - ldap_pvt_thread_mutex_lock( op->o_bd->be_pcl_mutexp ); -#if 0 - if ( op->o_sync_csn.bv_val ) free( op->o_sync_csn.bv_val ); - ber_dupbv( &op->o_sync_csn, csn ); -#endif - pending->ce_csn = ber_dupbv( NULL, csn ); - pending->ce_connid = op->o_connid; - pending->ce_opid = op->o_opid; - pending->ce_state = SLAP_CSN_PENDING; - LDAP_TAILQ_INSERT_TAIL( op->o_bd->be_pending_csn_list, - pending, ce_csn_link ); - ldap_pvt_thread_mutex_unlock( op->o_bd->be_pcl_mutexp ); - } + if ( manage_ctxcsn ) + slap_queue_csn( op, csn ); return LDAP_SUCCESS; } diff --git a/servers/slapd/overlays/syncprov.c b/servers/slapd/overlays/syncprov.c index 5e67191fba..914f6cc034 100644 --- a/servers/slapd/overlays/syncprov.c +++ b/servers/slapd/overlays/syncprov.c @@ -51,6 +51,7 @@ typedef struct syncprov_info_t { int si_gotcsn; /* is our ctxcsn up to date? */ ldap_pvt_thread_mutex_t si_csn_mutex; ldap_pvt_thread_mutex_t si_ops_mutex; + char si_ctxcsnbuf[LDAP_LUTIL_CSNSTR_BUFSIZE]; } syncprov_info_t; typedef struct opcookie { @@ -568,17 +569,16 @@ syncprov_op_response( Operation *op, SlapReply *rs ) { struct berval maxcsn; char cbuf[LDAP_LUTIL_CSNSTR_BUFSIZE]; - void *memctx = op->o_tmpmemctx; cbuf[0] = '\0'; ldap_pvt_thread_mutex_lock( &si->si_csn_mutex ); - op->o_tmpmemctx = NULL; slap_get_commit_csn( op, &maxcsn ); - op->o_tmpmemctx = memctx; if ( maxcsn.bv_val ) { strcpy( cbuf, maxcsn.bv_val ); - free( si->si_ctxcsn.bv_val ); - si->si_ctxcsn = maxcsn; + if ( ber_bvcmp( &maxcsn, &si->si_ctxcsn ) > 0 ) { + strcpy( si->si_ctxcsnbuf, cbuf ); + si->si_ctxcsn.bv_len = maxcsn.bv_len; + } si->si_gotcsn = 1; } ldap_pvt_thread_mutex_unlock( &si->si_csn_mutex ); @@ -731,18 +731,24 @@ syncprov_search_response( Operation *op, SlapReply *rs ) if ( rs->sr_type == REP_SEARCH || rs->sr_type == REP_SEARCHREF ) { int i; + struct berval cookie; + + Attribute *a = attr_find( rs->sr_entry->e_attrs, + slap_schema.si_ad_entryCSN ); + if ( srs->sr_state.ctxcsn ) { - Attribute *a = attr_find( rs->sr_entry->e_attrs, - slap_schema.si_ad_entryCSN ); /* Don't send the ctx entry twice */ if ( bvmatch( &a->a_nvals[0], srs->sr_state.ctxcsn )) return LDAP_SUCCESS; } + slap_compose_sync_cookie( op, &cookie, a->a_nvals, + srs->sr_state.sid, srs->sr_state.rid ); + rs->sr_ctrls = op->o_tmpalloc( sizeof(LDAPControl *)*2, op->o_tmpmemctx ); rs->sr_ctrls[1] = NULL; rs->sr_err = slap_build_sync_state_ctrl( op, rs, rs->sr_entry, - LDAP_SYNC_ADD, rs->sr_ctrls, 0, 0, NULL ); + LDAP_SYNC_ADD, rs->sr_ctrls, 0, 1, &cookie ); } else if ( rs->sr_type == REP_RESULT && rs->sr_err == LDAP_SUCCESS ) { struct berval cookie; @@ -862,6 +868,7 @@ syncprov_op_search( Operation *op, SlapReply *rs ) ctrls[1] = NULL; slap_build_sync_done_ctrl( op, rs, ctrls, 0, 0, NULL, LDAP_SYNC_REFRESH_DELETES ); + rs->sr_ctrls = ctrls; rs->sr_err = LDAP_SUCCESS; send_ldap_result( op, rs ); return rs->sr_err; @@ -990,6 +997,7 @@ syncprov_db_init( on->on_bi.bi_private = si; ldap_pvt_thread_mutex_init( &si->si_csn_mutex ); ldap_pvt_thread_mutex_init( &si->si_ops_mutex ); + si->si_ctxcsn.bv_val = si->si_ctxcsnbuf; csn_anlist[0].an_desc = slap_schema.si_ad_entryCSN; csn_anlist[0].an_name = slap_schema.si_ad_entryCSN->ad_cname; diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h index 58980377b7..2f9bf95b22 100644 --- a/servers/slapd/proto-slap.h +++ b/servers/slapd/proto-slap.h @@ -486,6 +486,7 @@ LDAP_SLAPD_F (void) slap_rewind_commit_csn LDAP_P(( Operation * )); LDAP_SLAPD_F (void) slap_graduate_commit_csn LDAP_P(( Operation * )); LDAP_SLAPD_F (Entry *) slap_create_context_csn_entry LDAP_P(( Backend *, struct berval *)); LDAP_SLAPD_F (int) slap_get_csn LDAP_P(( Operation *, char *, int, struct berval *, int )); +LDAP_SLAPD_F (void) slap_queue_csn LDAP_P(( Operation *, struct berval * )); /* * daemon.c @@ -1265,7 +1266,8 @@ LDAP_SLAPD_F (int) syncrepl_message_to_entry LDAP_P(( LDAP_SLAPD_F (int) syncrepl_entry LDAP_P(( syncinfo_t *, Operation*, Entry*, Modifications*,int, struct berval*, - struct sync_cookie * )); + struct sync_cookie *, + struct berval * )); LDAP_SLAPD_F (void) syncrepl_updateCookie LDAP_P(( syncinfo_t *, Operation *, struct berval *, struct sync_cookie * )); diff --git a/servers/slapd/syncrepl.c b/servers/slapd/syncrepl.c index d9f01d29de..25a0946062 100644 --- a/servers/slapd/syncrepl.c +++ b/servers/slapd/syncrepl.c @@ -613,7 +613,7 @@ do_syncrep2( if ( syncrepl_message_to_entry( si, op, msg, &modlist, &entry, syncstate ) == LDAP_SUCCESS ) { rc_efree = syncrepl_entry( si, op, entry, modlist, - syncstate, &syncUUID, &syncCookie_req ); + syncstate, &syncUUID, &syncCookie_req, syncCookie.ctxcsn ); if ( syncCookie.octet_str && !BER_BVISNULL( &syncCookie.octet_str[0] ) ) { @@ -1162,7 +1162,8 @@ syncrepl_entry( Modifications* modlist, int syncstate, struct berval* syncUUID, - struct sync_cookie* syncCookie_req ) + struct sync_cookie* syncCookie_req, + struct berval* syncCSN ) { Backend *be = op->o_bd; slap_callback cb = { NULL }; @@ -1447,7 +1448,6 @@ syncrepl_entry( } done : - if ( !BER_BVISNULL( &syncUUID_strrep ) ) { slap_sl_free( syncUUID_strrep.bv_val, op->o_tmpmemctx ); BER_BVZERO( &syncUUID_strrep ); @@ -1885,6 +1885,8 @@ syncrepl_updateCookie( op->o_req_dn = e->e_name; op->o_req_ndn = e->e_nname; + slap_queue_csn( op, syncCookie->ctxcsn ); + /* update persistent cookie */ update_cookie_retry: op->o_tag = LDAP_REQ_MODIFY; @@ -1919,6 +1921,7 @@ update_cookie_retry: "be_modify failed (%d)\n", rs_modify.sr_err, 0, 0 ); } } + slap_graduate_commit_csn( op ); if ( e != NULL ) { entry_free( e ); -- 2.39.5