mirror of
https://git.openldap.org/openldap/openldap.git
synced 2024-12-21 03:10:25 +08:00
Optimization: send sid in cookie to avoid getting our changes sent
back to us.
This commit is contained in:
parent
96b1ccb934
commit
250cbd286a
@ -35,7 +35,8 @@ slap_compose_sync_cookie(
|
||||
Operation *op,
|
||||
struct berval *cookie,
|
||||
BerVarray csn,
|
||||
int rid )
|
||||
int rid,
|
||||
int sid )
|
||||
{
|
||||
int len, numcsn = 0;
|
||||
|
||||
@ -51,6 +52,9 @@ slap_compose_sync_cookie(
|
||||
} else {
|
||||
len = snprintf( cookiestr, sizeof( cookiestr ),
|
||||
"rid=%03d", rid );
|
||||
if ( sid >= 0 ) {
|
||||
len += sprintf( cookiestr+len, ",sid=%03x", sid );
|
||||
}
|
||||
}
|
||||
ber_str2bv_x( cookiestr, len, 1, cookie,
|
||||
op ? op->o_tmpmemctx : NULL );
|
||||
@ -63,10 +67,17 @@ slap_compose_sync_cookie(
|
||||
len += csn[i].bv_len + 1;
|
||||
|
||||
len += STRLENOF("rid=123,csn=");
|
||||
if ( sid >= 0 )
|
||||
len += STRLENOF("sid=xxx,");
|
||||
|
||||
cookie->bv_val = slap_sl_malloc( len, op ? op->o_tmpmemctx : NULL );
|
||||
|
||||
len = sprintf( cookie->bv_val, "rid=%03d,csn=", rid );
|
||||
len = sprintf( cookie->bv_val, "rid=%03d,", rid );
|
||||
ptr = cookie->bv_val + len;
|
||||
if ( sid >= 0 ) {
|
||||
ptr += sprintf( ptr, "sid=%03x,", sid );
|
||||
}
|
||||
ptr = lutil_strcopy( ptr, "csn=" );
|
||||
for ( i=0; i<numcsn; i++) {
|
||||
ptr = lutil_strncopy( ptr, csn[i].bv_val, csn[i].bv_len );
|
||||
*ptr++ = ';';
|
||||
@ -160,6 +171,7 @@ slap_parse_sync_cookie(
|
||||
return -1;
|
||||
|
||||
cookie->rid = -1;
|
||||
cookie->sid = -1;
|
||||
cookie->ctxcsn = NULL;
|
||||
cookie->sids = NULL;
|
||||
cookie->numcsns = 0;
|
||||
@ -181,6 +193,17 @@ slap_parse_sync_cookie(
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if ( !strncmp( next, "sid=", STRLENOF("sid=") )) {
|
||||
rid_ptr = next;
|
||||
cookie->sid = strtoul( &rid_ptr[ STRLENOF( "sid=" ) ], &next, 16 );
|
||||
if ( next == rid_ptr || next > end || *next != ',' ) {
|
||||
return -1;
|
||||
}
|
||||
if ( *next == ',' ) {
|
||||
next++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if ( !strncmp( next, "csn=", STRLENOF("csn=") )) {
|
||||
slap_syntax_validate_func *validate;
|
||||
struct berval stamp;
|
||||
@ -258,6 +281,7 @@ slap_init_sync_cookie_ctxcsn(
|
||||
cookie->ctxcsn = NULL;
|
||||
value_add_one( &cookie->ctxcsn, &ctxcsn );
|
||||
cookie->numcsns = 1;
|
||||
cookie->sid = slap_serverID;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -287,6 +311,7 @@ slap_dup_sync_cookie(
|
||||
}
|
||||
|
||||
new->rid = src->rid;
|
||||
new->sid = src->sid;
|
||||
new->numcsns = src->numcsns;
|
||||
|
||||
if ( src->numcsns ) {
|
||||
|
@ -59,6 +59,7 @@ typedef struct syncops {
|
||||
ID s_eid; /* entryID of search base */
|
||||
Operation *s_op; /* search op */
|
||||
int s_rid;
|
||||
int s_sid;
|
||||
struct berval s_filterstr;
|
||||
int s_flags; /* search status */
|
||||
#define PS_IS_REFRESHING 0x01
|
||||
@ -769,7 +770,7 @@ syncprov_sendresp( Operation *op, opcookie *opc, syncops *so,
|
||||
ctrls[1] = NULL;
|
||||
csns[0] = opc->sctxcsn;
|
||||
BER_BVZERO( &csns[1] );
|
||||
slap_compose_sync_cookie( op, &cookie, csns, so->s_rid );
|
||||
slap_compose_sync_cookie( op, &cookie, csns, so->s_rid, so->s_sid );
|
||||
|
||||
e_uuid.e_attrs = &a_uuid;
|
||||
a_uuid.a_desc = slap_schema.si_ad_entryUUID;
|
||||
@ -977,6 +978,12 @@ static int
|
||||
syncprov_qresp( opcookie *opc, syncops *so, int mode )
|
||||
{
|
||||
syncres *sr;
|
||||
int sid;
|
||||
|
||||
/* Don't send changes back to their originator */
|
||||
sid = slap_parse_csn_sid( &opc->sctxcsn );
|
||||
if ( sid == so->s_sid )
|
||||
return LDAP_SUCCESS;
|
||||
|
||||
sr = ch_malloc(sizeof(syncres) + opc->suuid.bv_len + 1 +
|
||||
opc->sdn.bv_len + 1 + opc->sndn.bv_len + 1 + opc->sctxcsn.bv_len + 1 );
|
||||
@ -1523,7 +1530,8 @@ syncprov_playlog( Operation *op, SlapReply *rs, sessionlog *sl,
|
||||
if ( ndel ) {
|
||||
struct berval cookie;
|
||||
|
||||
slap_compose_sync_cookie( op, &cookie, delcsn, srs->sr_state.rid );
|
||||
slap_compose_sync_cookie( op, &cookie, delcsn, srs->sr_state.rid,
|
||||
srs->sr_state.sid );
|
||||
uuids[ndel].bv_val = NULL;
|
||||
syncprov_sendinfo( op, rs, LDAP_TAG_SYNC_ID_SET, &cookie, 0, uuids, 1 );
|
||||
op->o_tmpfree( cookie.bv_val, op->o_tmpmemctx );
|
||||
@ -1919,6 +1927,13 @@ 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 ) {
|
||||
Debug( LDAP_DEBUG_SYNC,
|
||||
"Entry %s changed by peer, ignored\n",
|
||||
rs->sr_entry->e_name.bv_val, 0, 0 );
|
||||
return LDAP_SUCCESS;
|
||||
}
|
||||
/* Make sure entry is less than the snapshot'd contextCSN */
|
||||
for ( i=0; i<ss->ss_numcsns; i++ ) {
|
||||
if ( sid == ss->ss_sids[i] && ber_bvcmp( &a->a_nvals[0],
|
||||
@ -1957,7 +1972,7 @@ syncprov_search_response( Operation *op, SlapReply *rs )
|
||||
struct berval cookie;
|
||||
|
||||
slap_compose_sync_cookie( op, &cookie, ss->ss_ctxcsn,
|
||||
srs->sr_state.rid );
|
||||
srs->sr_state.rid, srs->sr_state.sid );
|
||||
|
||||
/* Is this a regular refresh? */
|
||||
if ( !ss->ss_so ) {
|
||||
@ -2051,6 +2066,7 @@ syncprov_op_search( Operation *op, SlapReply *rs )
|
||||
*sop = so;
|
||||
ldap_pvt_thread_mutex_init( &sop->s_mutex );
|
||||
sop->s_rid = srs->sr_state.rid;
|
||||
sop->s_rid = srs->sr_state.sid;
|
||||
sop->s_inuse = 1;
|
||||
|
||||
ldap_pvt_thread_mutex_lock( &si->si_ops_mutex );
|
||||
|
@ -1016,7 +1016,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 ));
|
||||
Operation *, struct berval *, BerVarray, int, int ));
|
||||
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((
|
||||
|
@ -1661,6 +1661,7 @@ struct sync_cookie {
|
||||
struct berval *ctxcsn;
|
||||
struct berval octet_str;
|
||||
int rid;
|
||||
int sid;
|
||||
int numcsns;
|
||||
int *sids;
|
||||
LDAP_STAILQ_ENTRY(sync_cookie) sc_next;
|
||||
|
@ -520,13 +520,14 @@ do_syncrep1(
|
||||
}
|
||||
|
||||
slap_compose_sync_cookie( NULL, &si->si_syncCookie.octet_str,
|
||||
si->si_syncCookie.ctxcsn, si->si_syncCookie.rid );
|
||||
si->si_syncCookie.ctxcsn, si->si_syncCookie.rid,
|
||||
SLAP_SINGLE_SHADOW( si->si_be ) ? -1 : slap_serverID );
|
||||
} else {
|
||||
ldap_pvt_thread_mutex_lock( &si->si_cookieState->cs_mutex );
|
||||
/* match SIDs */
|
||||
if ( si->si_cookieState->cs_num > 1 && si->si_cookieAge !=
|
||||
si->si_cookieState->cs_age ) {
|
||||
int i, j;
|
||||
int i, j, changed = 0;
|
||||
|
||||
for (i=0; !BER_BVISNULL( &si->si_syncCookie.ctxcsn[i] ); i++) {
|
||||
/* bogus, just dup everything */
|
||||
@ -534,6 +535,7 @@ do_syncrep1(
|
||||
ber_bvarray_free( si->si_syncCookie.ctxcsn );
|
||||
ber_bvarray_dup_x( &si->si_syncCookie.ctxcsn,
|
||||
si->si_cookieState->cs_vals, NULL );
|
||||
changed = 1;
|
||||
break;
|
||||
}
|
||||
for (j=0; j<si->si_cookieState->cs_num; j++) {
|
||||
@ -542,9 +544,16 @@ do_syncrep1(
|
||||
continue;
|
||||
ber_bvreplace( &si->si_syncCookie.ctxcsn[i],
|
||||
&si->si_cookieState->cs_vals[j] );
|
||||
changed = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( changed ) {
|
||||
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,
|
||||
SLAP_SINGLE_SHADOW( si->si_be ) ? -1 : slap_serverID );
|
||||
}
|
||||
}
|
||||
ldap_pvt_thread_mutex_unlock( &si->si_cookieState->cs_mutex );
|
||||
}
|
||||
@ -1092,6 +1101,13 @@ reload:
|
||||
goto reload;
|
||||
}
|
||||
|
||||
/* We got deleted while running on cn=config */
|
||||
if ( !si->si_ctype ) {
|
||||
if ( si->si_conn_setup )
|
||||
dostop = 1;
|
||||
rc = -1;
|
||||
}
|
||||
|
||||
if ( abs(si->si_type) == LDAP_SYNC_REFRESH_AND_PERSIST ) {
|
||||
/* If we succeeded, enable the connection for further listening.
|
||||
* If we failed, tear down the connection and reschedule.
|
||||
@ -1146,7 +1162,8 @@ reload:
|
||||
break;
|
||||
}
|
||||
|
||||
if ( !si->si_retrynum || si->si_retrynum[i] == RETRYNUM_TAIL ) {
|
||||
if ( !si->si_ctype
|
||||
|| !si->si_retrynum || si->si_retrynum[i] == RETRYNUM_TAIL ) {
|
||||
ldap_pvt_runqueue_remove( &slapd_rq, rtask );
|
||||
} else if ( RETRYNUM_VALID( si->si_retrynum[i] ) ) {
|
||||
if ( si->si_retrynum[i] > 0 )
|
||||
@ -1160,6 +1177,24 @@ reload:
|
||||
ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex );
|
||||
ldap_pvt_thread_mutex_unlock( &si->si_mutex );
|
||||
|
||||
/* Do final delete cleanup */
|
||||
if ( !si->si_ctype ) {
|
||||
cookie_state *cs = NULL;
|
||||
syncinfo_t **sip;
|
||||
|
||||
cs = be->be_syncinfo->si_cookieState;
|
||||
for ( sip = &be->be_syncinfo; *sip != si; sip = &(*sip)->si_next );
|
||||
*sip = si->si_next;
|
||||
syncinfo_free( si );
|
||||
if ( !be->be_syncinfo ) {
|
||||
SLAP_DBFLAGS( be ) &= ~(SLAP_DBFLAG_SHADOW|SLAP_DBFLAG_SYNC_SHADOW);
|
||||
if ( cs ) {
|
||||
ber_bvarray_free( cs->cs_vals );
|
||||
ldap_pvt_thread_mutex_destroy( &cs->cs_mutex );
|
||||
ch_free( cs );
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -3836,7 +3871,18 @@ syncrepl_config( ConfigArgs *c )
|
||||
si = *sip;
|
||||
if ( c->valx == -1 || i == c->valx ) {
|
||||
*sip = si->si_next;
|
||||
/* If the task is currently active, we have to leave
|
||||
* it running. It will exit on its own. This will only
|
||||
* happen when running on the cn=config DB.
|
||||
*/
|
||||
if ( si->si_re &&
|
||||
ldap_pvt_runqueue_isrunning( &slapd_rq, si->si_re ) ) {
|
||||
si->si_ctype = 0;
|
||||
} else {
|
||||
syncinfo_free( si );
|
||||
}
|
||||
if ( i == c->valx )
|
||||
break;
|
||||
} else {
|
||||
sip = &si->si_next;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user