From ec209b60426f2230dee5479b9393c368d752ba7e Mon Sep 17 00:00:00 2001 From: Quanah Gibson-Mount Date: Sat, 21 Nov 2009 19:16:57 +0000 Subject: [PATCH] Use unique IDs for fake syncrepl connections in updateCookie, no-op if nothing changed in op_response, rearrange contextCSN update checks --- servers/slapd/overlays/syncprov.c | 100 ++++++++++++++---------------- servers/slapd/syncrepl.c | 8 ++- 2 files changed, 52 insertions(+), 56 deletions(-) diff --git a/servers/slapd/overlays/syncprov.c b/servers/slapd/overlays/syncprov.c index c34e90bc42..bd77ebe129 100644 --- a/servers/slapd/overlays/syncprov.c +++ b/servers/slapd/overlays/syncprov.c @@ -1671,7 +1671,50 @@ syncprov_op_response( Operation *op, SlapReply *rs ) maxcsn.bv_len = sizeof(cbuf); ldap_pvt_thread_rdwr_wlock( &si->si_csn_rwlock ); - if ( op->o_dont_replicate && op->o_tag == LDAP_REQ_MODIFY && + slap_get_commit_csn( op, &maxcsn, &foundit ); + if ( BER_BVISEMPTY( &maxcsn ) && SLAP_GLUE_SUBORDINATE( op->o_bd )) { + /* syncrepl queues the CSN values in the db where + * it is configured , not where the changes are made. + * So look for a value in the glue db if we didn't + * find any in this db. + */ + BackendDB *be = op->o_bd; + op->o_bd = select_backend( &be->be_nsuffix[0], 1); + maxcsn.bv_val = cbuf; + maxcsn.bv_len = sizeof(cbuf); + slap_get_commit_csn( op, &maxcsn, &foundit ); + op->o_bd = be; + } + if ( !BER_BVISEMPTY( &maxcsn ) ) { + int i, sid; +#ifdef CHECK_CSN + Syntax *syn = slap_schema.si_ad_contextCSN->ad_type->sat_syntax; + assert( !syn->ssyn_validate( syn, &maxcsn )); +#endif + sid = slap_parse_csn_sid( &maxcsn ); + for ( i=0; isi_numcsns; i++ ) { + if ( sid == si->si_sids[i] ) { + if ( ber_bvcmp( &maxcsn, &si->si_ctxcsn[i] ) > 0 ) { + ber_bvreplace( &si->si_ctxcsn[i], &maxcsn ); + csn_changed = 1; + } + break; + } + } + /* It's a new SID for us */ + if ( i == si->si_numcsns ) { + value_add_one( &si->si_ctxcsn, &maxcsn ); + csn_changed = 1; + si->si_numcsns++; + si->si_sids = ch_realloc( si->si_sids, si->si_numcsns * + sizeof(int)); + si->si_sids[i] = sid; + } + } + + /* 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 ) { /* Catch contextCSN updates from syncrepl. We have to look at @@ -1683,7 +1726,6 @@ syncprov_op_response( Operation *op, SlapReply *rs ) for ( i=0; isml_numvals; i++ ) { sid = slap_parse_csn_sid( &mod->sml_values[i] ); - for ( j=0; jsi_numcsns; j++ ) { if ( sid == si->si_sids[j] ) { if ( ber_bvcmp( &mod->sml_values[i], &si->si_ctxcsn[j] ) > 0 ) { @@ -1718,59 +1760,9 @@ syncprov_op_response( Operation *op, SlapReply *rs ) } } } - goto leave; - } - - slap_get_commit_csn( op, &maxcsn, &foundit ); - if ( BER_BVISEMPTY( &maxcsn ) && SLAP_GLUE_SUBORDINATE( op->o_bd )) { - /* syncrepl queues the CSN values in the db where - * it is configured , not where the changes are made. - * So look for a value in the glue db if we didn't - * find any in this db. - */ - BackendDB *be = op->o_bd; - op->o_bd = select_backend( &be->be_nsuffix[0], 1); - maxcsn.bv_val = cbuf; - maxcsn.bv_len = sizeof(cbuf); - slap_get_commit_csn( op, &maxcsn, &foundit ); - op->o_bd = be; - } - if ( !BER_BVISEMPTY( &maxcsn ) ) { - int i, sid; -#ifdef CHECK_CSN - Syntax *syn = slap_schema.si_ad_contextCSN->ad_type->sat_syntax; - assert( !syn->ssyn_validate( syn, &maxcsn )); -#endif - sid = slap_parse_csn_sid( &maxcsn ); - for ( i=0; isi_numcsns; i++ ) { - if ( sid == si->si_sids[i] ) { - if ( ber_bvcmp( &maxcsn, &si->si_ctxcsn[i] ) > 0 ) { - ber_bvreplace( &si->si_ctxcsn[i], &maxcsn ); - csn_changed = 1; - } - break; - } - } - /* It's a new SID for us */ - if ( i == si->si_numcsns ) { - value_add_one( &si->si_ctxcsn, &maxcsn ); - csn_changed = 1; - si->si_numcsns++; - si->si_sids = ch_realloc( si->si_sids, si->si_numcsns * - sizeof(int)); - si->si_sids[i] = sid; - } -#if 0 - } else if ( !foundit ) { - /* internal ops that aren't meant to be replicated */ - ldap_pvt_thread_rdwr_wunlock( &si->si_csn_rwlock ); - return SLAP_CB_CONTINUE; -#endif - } - - /* Don't do any processing for consumer contextCSN updates */ - if ( op->o_dont_replicate ) { + } else { ldap_pvt_thread_rdwr_wunlock( &si->si_csn_rwlock ); + } goto leave; } diff --git a/servers/slapd/syncrepl.c b/servers/slapd/syncrepl.c index aadf33b79c..414ab32506 100644 --- a/servers/slapd/syncrepl.c +++ b/servers/slapd/syncrepl.c @@ -1353,6 +1353,8 @@ do_syncrepl( connection_fake_init( &conn, &opbuf, ctx ); op = &opbuf.ob_op; + /* o_connids must be unique for slap_graduate_commit_csn */ + op->o_connid = -1000 - si->si_rid; op->o_managedsait = SLAP_CONTROL_NONCRITICAL; be = si->si_be; @@ -3023,7 +3025,7 @@ syncrepl_updateCookie( Syntax *syn = slap_schema.si_ad_contextCSN->ad_type->sat_syntax; #endif - int rc, i, j; + int rc, i, j, changed = 0; ber_len_t len; slap_callback cb = { NULL }; @@ -3065,6 +3067,7 @@ syncrepl_updateCookie( if ( memcmp( syncCookie->ctxcsn[i].bv_val, si->si_cookieState->cs_vals[j].bv_val, len ) > 0 ) { mod.sml_values[j] = syncCookie->ctxcsn[i]; + changed = 1; if ( BER_BVISNULL( &first ) ) { first = syncCookie->ctxcsn[i]; @@ -3087,10 +3090,11 @@ syncrepl_updateCookie( { first = syncCookie->ctxcsn[i]; } + changed = 1; } } /* Should never happen, ITS#5065 */ - if ( BER_BVISNULL( &first )) { + if ( BER_BVISNULL( &first ) || !changed ) { ldap_pvt_thread_mutex_unlock( &si->si_cookieState->cs_mutex ); op->o_tmpfree( mod.sml_values, op->o_tmpmemctx ); return 0; -- 2.39.2