From d1e874c605233de3ecb4dfb44e12dfb9f7acb267 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Kuzn=C3=ADk?= Date: Tue, 9 Oct 2018 12:24:04 +0200 Subject: [PATCH 1/3] ITS#8768 Introduce delcsn into our syncrepl cookies --- servers/slapd/ldapsync.c | 63 ++++++++++++++++++++++++++++++- servers/slapd/overlays/syncprov.c | 13 ++++--- servers/slapd/proto-slap.h | 2 +- servers/slapd/slap.h | 1 + servers/slapd/syncrepl.c | 8 ++-- 5 files changed, 76 insertions(+), 11 deletions(-) diff --git a/servers/slapd/ldapsync.c b/servers/slapd/ldapsync.c index c120bdf30c..9f30dce5d3 100644 --- a/servers/slapd/ldapsync.c +++ b/servers/slapd/ldapsync.c @@ -36,7 +36,8 @@ slap_compose_sync_cookie( struct berval *cookie, BerVarray csn, int rid, - int sid ) + int sid, + struct berval *delcsn ) { int len, numcsn = 0; @@ -65,6 +66,8 @@ slap_compose_sync_cookie( len = 0; for ( i=0; ibv_len; len += STRLENOF("rid=123,csn="); if ( sid >= 0 ) @@ -83,6 +86,10 @@ slap_compose_sync_cookie( *ptr++ = ';'; } ptr--; + if ( delcsn && !BER_BVISEMPTY(delcsn) ) { + ptr = lutil_strcopy( ptr, ",delcsn=" ); + ptr = lutil_strncopy( ptr, delcsn->bv_val, delcsn->bv_len ); + } *ptr = '\0'; cookie->bv_len = ptr - cookie->bv_val; } @@ -112,6 +119,11 @@ slap_sync_cookie_free( BER_BVZERO( &cookie->octet_str ); } + if ( !BER_BVISNULL( &cookie->delcsn )) { + ch_free( cookie->delcsn.bv_val ); + BER_BVZERO( &cookie->delcsn ); + } + if ( free_cookie ) { ch_free( cookie ); } @@ -273,6 +285,7 @@ slap_parse_sync_cookie( cookie->ctxcsn = NULL; cookie->sids = NULL; cookie->numcsns = 0; + BER_BVZERO( &cookie->delcsn ); end = cookie->octet_str.bv_val + cookie->octet_str.bv_len; @@ -359,6 +372,49 @@ slap_parse_sync_cookie( } continue; } + if ( !strncmp( next, "delcsn=", STRLENOF("delcsn=") )) { + struct berval stamp; + + next += STRLENOF("delcsn="); + while ( next < end ) { + csn_str = next; + csn_ptr = strchr( csn_str, '#' ); + if ( !csn_ptr || csn_ptr > end ) + break; + /* ad will be NULL when called from main. we just + * want to parse the rid then. But we still iterate + * through the string to find the end. + */ + cval = strchr( csn_ptr, ';' ); + if ( !cval ) + cval = strchr(csn_ptr, ',' ); + if ( cval ) + stamp.bv_len = cval - csn_str; + else + stamp.bv_len = end - csn_str; + if ( ad ) { + struct berval bv; + stamp.bv_val = csn_str; + if ( ad->ad_type->sat_syntax->ssyn_validate( + ad->ad_type->sat_syntax, &stamp ) != LDAP_SUCCESS ) + break; + if ( ad->ad_type->sat_equality->smr_normalize( + SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX, + ad->ad_type->sat_syntax, + ad->ad_type->sat_equality, + &stamp, &bv, memctx ) != LDAP_SUCCESS ) + break; + cookie->delcsn = bv; + } + if ( cval ) { + next = cval + 1; + } else { + next = end; + } + break; + } + continue; + } next++; } if ( cookie->numcsns ) { @@ -411,6 +467,7 @@ slap_init_sync_cookie_ctxcsn( value_add_one( &cookie->ctxcsn, &ctxcsn ); cookie->numcsns = 1; cookie->sid = -1; + BER_BVZERO( &cookie->delcsn ); return 0; } @@ -455,6 +512,10 @@ slap_dup_sync_cookie( new->sids[i] = src->sids[i]; } + if ( !BER_BVISNULL( &src->delcsn )) { + ber_dupbv( &new->delcsn, &src->delcsn ); + } + if ( !BER_BVISNULL( &src->octet_str )) { ber_dupbv( &new->octet_str, &src->octet_str ); } diff --git a/servers/slapd/overlays/syncprov.c b/servers/slapd/overlays/syncprov.c index 8dfcc3a465..5ea9e81c9c 100644 --- a/servers/slapd/overlays/syncprov.c +++ b/servers/slapd/overlays/syncprov.c @@ -887,7 +887,8 @@ syncprov_sendresp( Operation *op, resinfo *ri, syncops *so, int mode ) rs.sr_flags = REP_CTRLS_MUSTBEFREED; csns[0] = ri->ri_csn; BER_BVZERO( &csns[1] ); - slap_compose_sync_cookie( op, &cookie, csns, so->s_rid, slap_serverID ? slap_serverID : -1 ); + slap_compose_sync_cookie( op, &cookie, csns, so->s_rid, + slap_serverID ? slap_serverID : -1, NULL ); #ifdef LDAP_DEBUG if ( so->s_sid > 0 ) { @@ -1139,7 +1140,7 @@ syncprov_qresp( opcookie *opc, syncops *so, int mode ) syncprov_info_t *si = opc->son->on_bi.bi_private; slap_compose_sync_cookie( NULL, &ri->ri_cookie, si->si_ctxcsn, - so->s_rid, slap_serverID ? slap_serverID : -1); + so->s_rid, slap_serverID ? slap_serverID : -1, NULL ); } Debug( LDAP_DEBUG_SYNC, "%s syncprov_qresp: " "set up a new syncres mode=%d csn=%s\n", @@ -1899,7 +1900,7 @@ syncprov_playlog( Operation *op, SlapReply *rs, sessionlog *sl, if ( delcsn[0].bv_len ) { slap_compose_sync_cookie( op, &cookie, delcsn, srs->sr_state.rid, - slap_serverID ? slap_serverID : -1 ); + slap_serverID ? slap_serverID : -1, delcsn ); Debug( LDAP_DEBUG_SYNC, "%s syncprov_playlog: cookie=%s\n", op->o_log_prefix, cookie.bv_val ); @@ -2537,7 +2538,8 @@ syncprov_search_response( Operation *op, SlapReply *rs ) /* If we're in delta-sync mode, always send a cookie */ if ( si->si_nopres && si->si_usehint && a ) { struct berval cookie; - slap_compose_sync_cookie( op, &cookie, a->a_nvals, srs->sr_state.rid, slap_serverID ? slap_serverID : -1 ); + slap_compose_sync_cookie( op, &cookie, a->a_nvals, srs->sr_state.rid, + slap_serverID ? slap_serverID : -1, NULL ); rs->sr_err = syncprov_state_ctrl( op, rs, rs->sr_entry, LDAP_SYNC_ADD, rs->sr_ctrls, 0, 1, &cookie ); op->o_tmpfree( cookie.bv_val, op->o_tmpmemctx ); @@ -2551,7 +2553,8 @@ syncprov_search_response( Operation *op, SlapReply *rs ) if ( ( ss->ss_flags & SS_CHANGED ) && ss->ss_ctxcsn && !BER_BVISNULL( &ss->ss_ctxcsn[0] )) { slap_compose_sync_cookie( op, &cookie, ss->ss_ctxcsn, - srs->sr_state.rid, slap_serverID ? slap_serverID : -1 ); + srs->sr_state.rid, + slap_serverID ? slap_serverID : -1, NULL ); Debug( LDAP_DEBUG_SYNC, "%s syncprov_search_response: cookie=%s\n", op->o_log_prefix, cookie.bv_val ); diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h index 0790a80040..628f165fed 100644 --- a/servers/slapd/proto-slap.h +++ b/servers/slapd/proto-slap.h @@ -1188,7 +1188,7 @@ LDAP_SLAPD_V (char *) slap_known_controls[]; * ldapsync.c */ LDAP_SLAPD_F (void) slap_compose_sync_cookie LDAP_P(( - Operation *, struct berval *, BerVarray, int, int )); + Operation *, struct berval *, BerVarray, int, int, struct berval * )); LDAP_SLAPD_F (void) slap_sync_cookie_free LDAP_P(( struct sync_cookie *, int free_cookie )); LDAP_SLAPD_F (int) slap_parse_csn_sid LDAP_P(( diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h index 38c6bf1c48..400f9bbc4c 100644 --- a/servers/slapd/slap.h +++ b/servers/slapd/slap.h @@ -1769,6 +1769,7 @@ struct sync_cookie { int numcsns; int rid; struct berval octet_str; + struct berval delcsn; int sid; LDAP_STAILQ_ENTRY(sync_cookie) sc_next; }; diff --git a/servers/slapd/syncrepl.c b/servers/slapd/syncrepl.c index afebf74b39..af5c3cef7a 100644 --- a/servers/slapd/syncrepl.c +++ b/servers/slapd/syncrepl.c @@ -764,7 +764,7 @@ check_syncprov( ch_free( si->si_syncCookie.octet_str.bv_val ); slap_compose_sync_cookie( NULL, &si->si_syncCookie.octet_str, si->si_syncCookie.ctxcsn, si->si_syncCookie.rid, - si->si_syncCookie.sid ); + si->si_syncCookie.sid, NULL ); ch_free( si->si_syncCookie.sids ); slap_reparse_sync_cookie( &si->si_syncCookie, op->o_tmpmemctx ); } @@ -927,7 +927,7 @@ do_syncrep1( ch_free( si->si_syncCookie.octet_str.bv_val ); slap_compose_sync_cookie( NULL, &si->si_syncCookie.octet_str, si->si_syncCookie.ctxcsn, si->si_syncCookie.rid, - si->si_syncCookie.sid ); + si->si_syncCookie.sid, NULL ); } else { /* ITS#6367: recreate the cookie so it has our SID, not our peer's */ ch_free( si->si_syncCookie.octet_str.bv_val ); @@ -937,7 +937,7 @@ do_syncrep1( if ( BER_BVISNULL( &si->si_syncCookie.octet_str )) slap_compose_sync_cookie( NULL, &si->si_syncCookie.octet_str, si->si_syncCookie.ctxcsn, si->si_syncCookie.rid, - si->si_syncCookie.sid ); + si->si_syncCookie.sid, NULL ); } } @@ -1852,7 +1852,7 @@ reload: if ( BER_BVISNULL( &si->si_syncCookie.octet_str )) slap_compose_sync_cookie( NULL, &si->si_syncCookie.octet_str, si->si_syncCookie.ctxcsn, si->si_syncCookie.rid, - si->si_syncCookie.sid ); + si->si_syncCookie.sid, NULL ); rc = ldap_sync_search( si, op->o_tmpmemctx ); goto reload; } -- GitLab From 182ec30a6b2e9cd39d78021719af61f88e639898 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Kuzn=C3=ADk?= Date: Tue, 9 Oct 2018 12:28:37 +0200 Subject: [PATCH 2/3] ITS#8768 Accept delcsn from the server --- servers/slapd/syncrepl.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/servers/slapd/syncrepl.c b/servers/slapd/syncrepl.c index af5c3cef7a..9a3bd920c5 100644 --- a/servers/slapd/syncrepl.c +++ b/servers/slapd/syncrepl.c @@ -4381,7 +4381,12 @@ syncrepl_del_nonpresent( if ( !LDAP_LIST_EMPTY( &si->si_nonpresentlist ) ) { - if ( sc->ctxcsn && !BER_BVISNULL( &sc->ctxcsn[m] ) ) { + if ( !BER_BVISNULL( &sc->delcsn ) ) { + Debug( LDAP_DEBUG_SYNC, "syncrepl_del_nonpresent: %s " + "using delcsn=%s\n", + si->si_ridtxt, sc->delcsn.bv_val ); + csn = sc->delcsn; + } else if ( sc->ctxcsn && !BER_BVISNULL( &sc->ctxcsn[m] ) ) { csn = sc->ctxcsn[m]; } else { csn = si->si_syncCookie.ctxcsn[0]; -- GitLab From e24a6bf5c1dc3a90b7e3f3d302705caad07bc08f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Kuzn=C3=ADk?= Date: Tue, 9 Oct 2018 12:57:12 +0200 Subject: [PATCH 3/3] ITS#8768 Do not update main CSN during delete phase --- servers/slapd/overlays/syncprov.c | 276 ++++++++++++++++++------------ 1 file changed, 163 insertions(+), 113 deletions(-) diff --git a/servers/slapd/overlays/syncprov.c b/servers/slapd/overlays/syncprov.c index 5ea9e81c9c..9878251483 100644 --- a/servers/slapd/overlays/syncprov.c +++ b/servers/slapd/overlays/syncprov.c @@ -1714,21 +1714,114 @@ playlog_cb( Operation *op, SlapReply *rs ) return rs->sr_err; } -/* enter with sl->sl_mutex locked, release before returning */ -static void -syncprov_playlog( Operation *op, SlapReply *rs, sessionlog *sl, - sync_control *srs, BerVarray ctxcsn, int numcsns, int *sids ) +/* + * Check whether the last nmods UUIDs in the uuids list exist in the database + * and (still) match the op filter, zero out the bv_len of any that still exist + * and return the number of UUIDs we have confirmed are gone now. + */ +static int +check_uuidlist_presence( + Operation *op, + struct berval *uuids, + int len, + int nmods ) +{ + slap_overinst *on = (slap_overinst *)op->o_bd->bd_info; + Operation fop = *op; + SlapReply frs = { REP_RESULT }; + Filter mf, af; + AttributeAssertion eq = ATTRIBUTEASSERTION_INIT; + slap_callback cb = {0}; + int i, mods = nmods; + + fop.o_sync_mode = 0; + fop.o_callback = &cb; + fop.ors_limit = NULL; + fop.ors_tlimit = SLAP_NO_LIMIT; + fop.ors_attrs = slap_anlist_all_attributes; + fop.ors_attrsonly = 0; + fop.o_managedsait = SLAP_CONTROL_CRITICAL; + + af.f_choice = LDAP_FILTER_AND; + af.f_next = NULL; + af.f_and = &mf; + mf.f_choice = LDAP_FILTER_EQUALITY; + mf.f_ava = &eq; + mf.f_av_desc = slap_schema.si_ad_entryUUID; + mf.f_next = fop.ors_filter; + + fop.ors_filter = ⁡ + + cb.sc_response = playlog_cb; + + fop.o_bd->bd_info = (BackendInfo *)on->on_info; + for ( i=0; ibe_search( &fop, &frs ); + if ( cb.sc_private ) { + uuids[ len - 1 - i ].bv_len = 0; + mods--; + } + } + fop.o_bd->bd_info = (BackendInfo *)on; + + return mods; +} + +static int +syncprov_play_sessionlog( Operation *op, SlapReply *rs, sync_control *srs, + BerVarray ctxcsn, int numcsns, int *sids, + struct berval *mincsn, int minsid ) { slap_overinst *on = (slap_overinst *)op->o_bd->bd_info; + syncprov_info_t *si = (syncprov_info_t *)on->on_bi.bi_private; + sessionlog *sl = si->si_logs; + int i, j, ndel, num, nmods, mmods, do_play = 0, rc = -1; + BerVarray uuids, csns; + struct berval uuid[2] = {}, csn[2] = {}; slog_entry *se; - int i, j, ndel, num, nmods, mmods; - char cbuf[LDAP_PVT_CSNSTR_BUFSIZE]; - BerVarray uuids; - struct berval delcsn[2]; + TAvlnode *entry; + ldap_pvt_thread_mutex_lock( &sl->sl_mutex ); + /* Are there any log entries, and is the consumer state + * present in the session log? + */ if ( !sl->sl_num ) { ldap_pvt_thread_mutex_unlock( &sl->sl_mutex ); - return; + return rc; + } + assert( sl->sl_num > 0 ); + + for ( i=0; isl_numcsns; i++ ) { + /* SID not present == new enough */ + if ( minsid < sl->sl_sids[i] ) { + do_play = 1; + break; + } + /* SID present */ + if ( minsid == sl->sl_sids[i] ) { + /* new enough? */ + if ( ber_bvcmp( mincsn, &sl->sl_mincsn[i] ) >= 0 ) + do_play = 1; + break; + } + } + /* SID not present == new enough */ + if ( i == sl->sl_numcsns ) + do_play = 1; + + if ( !do_play ) { + ldap_pvt_thread_mutex_unlock( &sl->sl_mutex ); + return rc; } num = sl->sl_num; @@ -1737,13 +1830,12 @@ syncprov_playlog( Operation *op, SlapReply *rs, sessionlog *sl, sl->sl_playing++; ldap_pvt_thread_mutex_unlock( &sl->sl_mutex ); - uuids = op->o_tmpalloc( (num+1) * sizeof( struct berval ) + - num * UUID_LEN, op->o_tmpmemctx ); - uuids[0].bv_val = (char *)(uuids + num + 1); - - delcsn[0].bv_len = 0; - delcsn[0].bv_val = cbuf; - BER_BVZERO(&delcsn[1]); + uuids = op->o_tmpalloc( (num) * sizeof( struct berval ) + + num * UUID_LEN, op->o_tmpmemctx ); + uuids[0].bv_val = (char *)(uuids + num); + csns = op->o_tmpalloc( (num) * sizeof( struct berval ) + + num * LDAP_PVT_CSNSTR_BUFSIZE, op->o_tmpmemctx ); + csns[0].bv_val = (char *)(csns + num); /* Make a copy of the relevant UUIDs. Put the Deletes up front * and everything else at the end. Do this first so we can @@ -1759,10 +1851,11 @@ syncprov_playlog( Operation *op, SlapReply *rs, sessionlog *sl, char uuidstr[40]; lutil_uuidstr_from_normalized( se->se_uuid.bv_val, se->se_uuid.bv_len, uuidstr, 40 ); - Debug( LDAP_DEBUG_SYNC, "%s syncprov_playlog: " + Debug( LDAP_DEBUG_SYNC, "%s syncprov_play_sessionlog: " "log entry tag=%lu uuid=%s cookie=%s\n", op->o_log_prefix, se->se_tag, uuidstr, se->se_csn.bv_val ); } + ndel = 1; for ( k=0; ksr_state.numcsns; k++ ) { if ( se->se_sid == srs->sr_state.sids[k] ) { @@ -1771,7 +1864,7 @@ syncprov_playlog( Operation *op, SlapReply *rs, sessionlog *sl, } } if ( ndel <= 0 ) { - Debug( LDAP_DEBUG_SYNC, "%s syncprov_playlog: " + Debug( LDAP_DEBUG_SYNC, "%s syncprov_play_sessionlog: " "cmp %d, csn %s too old, skipping\n", op->o_log_prefix, ndel, se->se_csn.bv_val ); continue; @@ -1784,7 +1877,7 @@ syncprov_playlog( Operation *op, SlapReply *rs, sessionlog *sl, } } if ( ndel > 0 ) { - Debug( LDAP_DEBUG_SYNC, "%s syncprov_playlog: " + Debug( LDAP_DEBUG_SYNC, "%s syncprov_play_sessionlog: " "cmp %d, csn %s too new, we're finished\n", op->o_log_prefix, ndel, se->se_csn.bv_val ); break; @@ -1792,9 +1885,6 @@ syncprov_playlog( Operation *op, SlapReply *rs, sessionlog *sl, if ( se->se_tag == LDAP_REQ_DELETE ) { j = i; i++; - AC_MEMCPY( cbuf, se->se_csn.bv_val, se->se_csn.bv_len ); - delcsn[0].bv_len = se->se_csn.bv_len; - delcsn[0].bv_val[delcsn[0].bv_len] = '\0'; } else { if ( se->se_tag == LDAP_REQ_ADD ) continue; @@ -1805,14 +1895,18 @@ syncprov_playlog( Operation *op, SlapReply *rs, sessionlog *sl, AC_MEMCPY(uuids[j].bv_val, se->se_uuid.bv_val, UUID_LEN); uuids[j].bv_len = UUID_LEN; + csns[j].bv_val = csns[0].bv_val + (j * LDAP_PVT_CSNSTR_BUFSIZE); + AC_MEMCPY(csns[j].bv_val, se->se_csn.bv_val, se->se_csn.bv_len); + csns[j].bv_len = se->se_csn.bv_len; + if ( LogTest( LDAP_DEBUG_SYNC ) ) { char uuidstr[40]; lutil_uuidstr_from_normalized( uuids[j].bv_val, uuids[j].bv_len, uuidstr, 40 ); - Debug( LDAP_DEBUG_SYNC, "%s syncprov_playlog: " + Debug( LDAP_DEBUG_SYNC, "%s syncprov_play_sessionlog: " "picking a %s entry uuid=%s cookie=%s\n", op->o_log_prefix, se->se_tag == LDAP_REQ_DELETE ? "deleted" : "modified", - uuidstr, delcsn[0].bv_len ? delcsn[0].bv_val : "(null)" ); + uuidstr, csns[j].bv_len ? csns[j].bv_val : "(null)" ); } } ldap_pvt_thread_mutex_lock( &sl->sl_mutex ); @@ -1848,72 +1942,57 @@ syncprov_playlog( Operation *op, SlapReply *rs, sessionlog *sl, } } + /* Check mods now */ if ( mmods ) { - Operation fop; - int rc; - Filter mf, af; - AttributeAssertion eq = ATTRIBUTEASSERTION_INIT; - slap_callback cb = {0}; - - fop = *op; - - fop.o_sync_mode = 0; - fop.o_callback = &cb; - fop.ors_limit = NULL; - fop.ors_tlimit = SLAP_NO_LIMIT; - fop.ors_attrs = slap_anlist_all_attributes; - fop.ors_attrsonly = 0; - fop.o_managedsait = SLAP_CONTROL_CRITICAL; - - af.f_choice = LDAP_FILTER_AND; - af.f_next = NULL; - af.f_and = &mf; - mf.f_choice = LDAP_FILTER_EQUALITY; - mf.f_ava = &eq; - mf.f_av_desc = slap_schema.si_ad_entryUUID; - mf.f_next = fop.ors_filter; - - fop.ors_filter = ⁡ - - cb.sc_response = playlog_cb; - fop.o_bd->bd_info = (BackendInfo *)on->on_info; + check_uuidlist_presence( op, uuids, num, nmods ); + } - for ( i=ndel; ibe_search( &fop, &frs ); + /* Skip over duplicate mods */ + if ( j < nmods && BER_BVISEMPTY( &uuids[ num - 1 - j ] ) ) { + j++; + continue; + } + index = num - 1 - j; - /* If entry was not found, add to delete list */ - if ( !cb.sc_private ) { - uuids[ndel++] = uuids[i]; - } - } + if ( i >= ndel ) { + j++; + } else if ( j >= nmods ) { + index = i++; + /* Take the oldest by CSN order */ + } else if ( ber_bvcmp( &csns[index], &csns[i] ) < 0 ) { + j++; + } else { + index = i++; } - fop.o_bd->bd_info = (BackendInfo *)on; - } - if ( ndel ) { - struct berval cookie; - if ( delcsn[0].bv_len ) { - slap_compose_sync_cookie( op, &cookie, delcsn, srs->sr_state.rid, - slap_serverID ? slap_serverID : -1, delcsn ); + uuid[0] = uuids[index]; + csn[0] = csns[index]; - Debug( LDAP_DEBUG_SYNC, "%s syncprov_playlog: cookie=%s\n", - op->o_log_prefix, cookie.bv_val ); + slap_compose_sync_cookie( op, &cookie, srs->sr_state.ctxcsn, + srs->sr_state.rid, slap_serverID ? slap_serverID : -1, csn ); + if ( LogTest( LDAP_DEBUG_SYNC ) ) { + char uuidstr[40]; + lutil_uuidstr_from_normalized( uuid[0].bv_val, uuid[0].bv_len, + uuidstr, 40 ); + Debug( LDAP_DEBUG_SYNC, "%s syncprov_play_sessionlog: " + "sending a new disappearing entry uuid=%s cookie=%s\n", + op->o_log_prefix, uuidstr, cookie.bv_val ); } - uuids[ndel].bv_val = NULL; - syncprov_sendinfo( op, rs, LDAP_TAG_SYNC_ID_SET, - delcsn[0].bv_len ? &cookie : NULL, 0, uuids, 1 ); - if ( delcsn[0].bv_len ) { - op->o_tmpfree( cookie.bv_val, op->o_tmpmemctx ); - } + /* TODO: we might batch those that share the same CSN (think present + * phase), but would have to limit how many we send out at once */ + syncprov_sendinfo( op, rs, LDAP_TAG_SYNC_ID_SET, &cookie, 0, uuid, 1 ); } op->o_tmpfree( uuids, op->o_tmpmemctx ); + op->o_tmpfree( csns, op->o_tmpmemctx ); + + return LDAP_SUCCESS; } static int @@ -2855,40 +2934,11 @@ no_change: if ( !(op->o_sync_mode & SLAP_SYNC_PERSIST) ) { goto shortcut; } - /* Do we have a sessionlog for this search? */ - sl=si->si_logs; - if ( sl ) { - int do_play = 0; - ldap_pvt_thread_mutex_lock( &sl->sl_mutex ); - /* Are there any log entries, and is the consumer state - * present in the session log? - */ - if ( sl->sl_num > 0 ) { - int i; - for ( i=0; isl_numcsns; i++ ) { - /* SID not present == new enough */ - if ( minsid < sl->sl_sids[i] ) { - do_play = 1; - break; - } - /* SID present */ - if ( minsid == sl->sl_sids[i] ) { - /* new enough? */ - if ( ber_bvcmp( &mincsn, &sl->sl_mincsn[i] ) >= 0 ) - do_play = 1; - break; - } - } - /* SID not present == new enough */ - if ( i == sl->sl_numcsns ) - do_play = 1; - } - if ( do_play ) { - do_present = 0; - /* mutex is unlocked in playlog */ - syncprov_playlog( op, rs, sl, srs, ctxcsn, numcsns, sids ); - } else { - ldap_pvt_thread_mutex_unlock( &sl->sl_mutex ); + if ( si->si_logs ) { + do_present = 0; + if ( syncprov_play_sessionlog( op, rs, srs, ctxcsn, + numcsns, sids, &mincsn, minsid ) ) { + do_present = SS_PRESENT; } } /* -- GitLab