int cs_ref;
struct berval *cs_vals;
int *cs_sids;
-} cookie_state;
+ /* pending changes, not yet committed */
+ ldap_pvt_thread_mutex_t cs_pmutex;
+ int cs_pnum;
+ struct berval *cs_pvals;
+ int *cs_psids;
+} cookie_state;
+
#define SYNCDATA_DEFAULT 0 /* entries are plain LDAP entries */
#define SYNCDATA_ACCESSLOG 1 /* entries are accesslog format */
#define SYNCDATA_CHANGELOG 2 /* entries are changelog format */
Modifications *modlist = NULL;
- int match, m;
+ int match, m, punlock = 0;
struct timeval *tout_p = NULL;
struct timeval tout = { 0, 0 };
if ( ber_peek_tag( ber, &len ) == LDAP_TAG_SYNC_COOKIE ) {
ber_scanf( ber, /*"{"*/ "m}", &cookie );
- Debug( LDAP_DEBUG_SYNC, "do_syncrep2: cookie=%s\n",
- BER_BVISNULL( &cookie ) ? "" : cookie.bv_val, 0, 0 );
+ Debug( LDAP_DEBUG_SYNC, "do_syncrep2: %s cookie=%s\n",
+ si->si_ridtxt,
+ BER_BVISNULL( &cookie ) ? "" : cookie.bv_val, 0 );
if ( !BER_BVISNULL( &cookie ) ) {
ch_free( syncCookie.octet_str.bv_val );
slap_parse_sync_cookie( &syncCookie, NULL );
if ( syncCookie.ctxcsn ) {
int i, sid = slap_parse_csn_sid( syncCookie.ctxcsn );
+ check_syncprov( op, si );
for ( i =0; i<si->si_cookieState->cs_num; i++ ) {
- if ( si->si_cookieState->cs_sids[i] == sid &&
- ber_bvcmp( syncCookie.ctxcsn, &si->si_cookieState->cs_vals[i] ) <= 0 ) {
- Debug( LDAP_DEBUG_SYNC, "do_syncrep2: %s CSN too old, ignoring %s\n",
- si->si_ridtxt, syncCookie.ctxcsn->bv_val, 0 );
- ldap_controls_free( rctrls );
- rc = 0;
+ if ( si->si_cookieState->cs_sids[i] == sid ) {
+ if ( ber_bvcmp( syncCookie.ctxcsn, &si->si_cookieState->cs_vals[i] ) <= 0 ) {
+ Debug( LDAP_DEBUG_SYNC, "do_syncrep2: %s CSN too old, ignoring %s\n",
+ si->si_ridtxt, syncCookie.ctxcsn->bv_val, 0 );
+ ldap_controls_free( rctrls );
+ rc = 0;
+ goto done;
+ }
+ break;
+ }
+ }
+ /* check pending CSNs too */
+ while ( ldap_pvt_thread_mutex_trylock( &si->si_cookieState->cs_pmutex )) {
+ if ( slapd_shutdown ) {
+ rc = -2;
goto done;
}
+ if ( !ldap_pvt_thread_pool_pausecheck( &connection_pool ))
+ ldap_pvt_thread_yield();
+ }
+ for ( i =0; i<si->si_cookieState->cs_pnum; i++ ) {
+ if ( si->si_cookieState->cs_psids[i] == sid ) {
+ if ( ber_bvcmp( syncCookie.ctxcsn, &si->si_cookieState->cs_pvals[i] ) <= 0 ) {
+ Debug( LDAP_DEBUG_SYNC, "do_syncrep2: %s CSN too old, ignoring %s\n",
+ si->si_ridtxt, syncCookie.ctxcsn->bv_val, 0 );
+ ldap_controls_free( rctrls );
+ rc = 0;
+ ldap_pvt_thread_mutex_unlock( &si->si_cookieState->cs_pmutex );
+ goto done;
+ }
+ ber_bvreplace( &si->si_cookieState->cs_pvals[i],
+ syncCookie.ctxcsn );
+ break;
+ }
+ }
+ /* new SID, add it */
+ if ( i == si->si_cookieState->cs_pnum ) {
+ value_add( &si->si_cookieState->cs_pvals, syncCookie.ctxcsn );
+ si->si_cookieState->cs_pnum++;
+ si->si_cookieState->cs_psids = ch_realloc( si->si_cookieState->cs_psids, si->si_cookieState->cs_pnum * sizeof(int));
+ si->si_cookieState->cs_psids[i] = sid;
}
+ punlock = 1;
}
op->o_controls[slap_cids.sc_LDAPsync] = &syncCookie;
}
rc = syncrepl_updateCookie( si, op, &syncCookie );
}
}
+ if ( punlock );
+ ldap_pvt_thread_mutex_unlock( &si->si_cookieState->cs_pmutex );
ldap_controls_free( rctrls );
if ( modlist ) {
slap_mods_free( modlist, 1 );
if ( ber_peek_tag( ber, &len ) == LDAP_TAG_SYNC_COOKIE ) {
ber_scanf( ber, "m", &cookie );
- Debug( LDAP_DEBUG_SYNC, "do_syncrep2: cookie=%s\n",
- BER_BVISNULL( &cookie ) ? "" : cookie.bv_val, 0, 0 );
+ Debug( LDAP_DEBUG_SYNC, "do_syncrep2: %s cookie=%s\n",
+ si->si_ridtxt,
+ BER_BVISNULL( &cookie ) ? "" : cookie.bv_val, 0 );
if ( !BER_BVISNULL( &cookie ) ) {
ch_free( syncCookie.octet_str.bv_val );
{
ber_scanf( ber, "m", &cookie );
- Debug( LDAP_DEBUG_SYNC, "do_syncrep2: cookie=%s\n",
- BER_BVISNULL( &cookie ) ? "" : cookie.bv_val, 0, 0 );
+ Debug( LDAP_DEBUG_SYNC, "do_syncrep2: %s cookie=%s\n",
+ si->si_ridtxt,
+ BER_BVISNULL( &cookie ) ? "" : cookie.bv_val, 0 );
if ( !BER_BVISNULL( &cookie ) ) {
ch_free( syncCookie.octet_str.bv_val );
{
ber_scanf( ber, "m", &cookie );
- Debug( LDAP_DEBUG_SYNC, "do_syncrep2: cookie=%s\n",
- BER_BVISNULL( &cookie ) ? "" : cookie.bv_val, 0, 0 );
+ Debug( LDAP_DEBUG_SYNC, "do_syncrep2: %s cookie=%s\n",
+ si->si_ridtxt,
+ BER_BVISNULL( &cookie ) ? "" : cookie.bv_val, 0 );
if ( !BER_BVISNULL( &cookie ) ) {
ch_free( syncCookie.octet_str.bv_val );
if ( sie->si_logbase.bv_val ) {
ch_free( sie->si_logbase.bv_val );
}
- if ( SLAP_SYNC_SUBENTRY( sie->si_be )) {
+ if ( sie->si_be && SLAP_SYNC_SUBENTRY( sie->si_be )) {
ch_free( sie->si_contextdn.bv_val );
}
if ( sie->si_attrs ) {
ch_free( sie->si_cookieState->cs_sids );
ber_bvarray_free( sie->si_cookieState->cs_vals );
ldap_pvt_thread_mutex_destroy( &sie->si_cookieState->cs_mutex );
+ ch_free( sie->si_cookieState->cs_psids );
+ ber_bvarray_free( sie->si_cookieState->cs_pvals );
+ ldap_pvt_thread_mutex_destroy( &sie->si_cookieState->cs_pmutex );
ch_free( sie->si_cookieState );
}
}
} else {
si->si_cookieState = ch_calloc( 1, sizeof( cookie_state ));
ldap_pvt_thread_mutex_init( &si->si_cookieState->cs_mutex );
+ ldap_pvt_thread_mutex_init( &si->si_cookieState->cs_pmutex );
c->be->be_syncinfo = si;
}