X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Foverlays%2Fsyncprov.c;h=48ca2ae919cc88acb7ea229deacb3cdcc9b0ee60;hb=59e9ff6243465640956b58ad1756a3ede53eca7c;hp=9cb2077947b9308a5f97914d75739caec927adf3;hpb=0eb577632f291db3e4f89cf4b496822b9766f7cc;p=openldap diff --git a/servers/slapd/overlays/syncprov.c b/servers/slapd/overlays/syncprov.c index 9cb2077947..48ca2ae919 100644 --- a/servers/slapd/overlays/syncprov.c +++ b/servers/slapd/overlays/syncprov.c @@ -2,7 +2,7 @@ /* syncprov.c - syncrepl provider */ /* This work is part of OpenLDAP Software . * - * Copyright 2004-2017 The OpenLDAP Foundation. + * Copyright 2004-2018 The OpenLDAP Foundation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -131,6 +131,7 @@ typedef struct sessionlog { int sl_numcsns; int sl_num; int sl_size; + int sl_playing; slog_entry *sl_head; slog_entry *sl_tail; ldap_pvt_thread_mutex_t sl_mutex; @@ -1552,12 +1553,15 @@ syncprov_add_slog( Operation *op ) * wipe out anything in the log if we see them. */ ldap_pvt_thread_mutex_lock( &sl->sl_mutex ); + /* can only do this if no one else is reading the log at the moment */ + if (!sl->sl_playing) { while ( se = sl->sl_head ) { sl->sl_head = se->se_next; ch_free( se ); } sl->sl_tail = NULL; sl->sl_num = 0; + } ldap_pvt_thread_mutex_unlock( &sl->sl_mutex ); return; } @@ -1608,6 +1612,7 @@ syncprov_add_slog( Operation *op ) } } sl->sl_num++; + if (!sl->sl_playing) { while ( sl->sl_num > sl->sl_size ) { int i; se = sl->sl_head; @@ -1624,6 +1629,7 @@ syncprov_add_slog( Operation *op ) ch_free( se ); sl->sl_num--; } + } ldap_pvt_thread_mutex_unlock( &sl->sl_mutex ); } } @@ -1658,6 +1664,8 @@ syncprov_playlog( Operation *op, SlapReply *rs, sessionlog *sl, num = sl->sl_num; i = 0; nmods = 0; + 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 ); @@ -1714,6 +1722,8 @@ 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; } + ldap_pvt_thread_mutex_lock( &sl->sl_mutex ); + sl->sl_playing--; ldap_pvt_thread_mutex_unlock( &sl->sl_mutex ); ndel = i; @@ -1924,23 +1934,26 @@ syncprov_op_response( Operation *op, SlapReply *rs ) } /* Don't do any processing for consumer contextCSN updates */ - if ( op->o_dont_replicate ) { - if ( op->o_tag == LDAP_REQ_MODIFY && - op->orm_modlist->sml_op == LDAP_MOD_REPLACE && - op->orm_modlist->sml_desc == slap_schema.si_ad_contextCSN ) { + if ( SLAPD_SYNC_IS_SYNCCONN( op->o_connid ) && + op->o_tag == LDAP_REQ_MODIFY && + op->orm_modlist->sml_op == LDAP_MOD_REPLACE && + op->orm_modlist->sml_desc == slap_schema.si_ad_contextCSN ) { /* Catch contextCSN updates from syncrepl. We have to look at * all the attribute values, as there may be more than one csn * that changed, and only one can be passed in the csn queue. */ - csn_changed = syncprov_new_ctxcsn( opc, si, csn_changed, - op->orm_modlist->sml_numvals, op->orm_modlist->sml_values ); - } else { - ldap_pvt_thread_rdwr_wunlock( &si->si_csn_rwlock ); - } + csn_changed = syncprov_new_ctxcsn( opc, si, csn_changed, + op->orm_modlist->sml_numvals, op->orm_modlist->sml_values ); if ( csn_changed ) si->si_numops++; goto leave; } + if ( op->o_dont_replicate ) { + if ( csn_changed ) + si->si_numops++; + ldap_pvt_thread_rdwr_wunlock( &si->si_csn_rwlock ); + goto leave; + } /* If we're adding the context entry, parse all of its contextCSNs */ if ( op->o_tag == LDAP_REQ_ADD && @@ -2388,14 +2401,6 @@ syncprov_search_response( Operation *op, SlapReply *rs ) int i, sid; sid = slap_parse_csn_sid( &a->a_nvals[0] ); - /* Don't send changed entries back to the originator */ - if ( sid == srs->sr_state.sid && srs->sr_state.numcsns ) { - Debug( LDAP_DEBUG_SYNC, - "Entry %s changed by peer, ignored\n", - rs->sr_entry->e_name.bv_val, 0, 0 ); - return LDAP_SUCCESS; - } - /* If not a persistent search */ if ( !ss->ss_so ) { /* Make sure entry is less than the snapshot'd contextCSN */