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,
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;
}
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 {
{
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 );
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;
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;
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;
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
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 * ));
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] ) )
{
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 };
}
done :
-
if ( !BER_BVISNULL( &syncUUID_strrep ) ) {
slap_sl_free( syncUUID_strrep.bv_val, op->o_tmpmemctx );
BER_BVZERO( &syncUUID_strrep );
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;
"be_modify failed (%d)\n", rs_modify.sr_err, 0, 0 );
}
}
+ slap_graduate_commit_csn( op );
if ( e != NULL ) {
entry_free( e );