--- servers/slapd/overlays/syncprov.c 2004/12/10 02:18:33 1.56
+++ servers/slapd/overlays/syncprov.c 2005/01/28 17:29:50 1.56.2.4
@@ -1,8 +1,8 @@
-/* $OpenLDAP: pkg/ldap/servers/slapd/overlays/syncprov.c,v 1.55 2004/12/10 01:51:34 hyc Exp $ */
+/* $OpenLDAP: pkg/ldap/servers/slapd/overlays/syncprov.c,v 1.56.2.3 2005/01/20 18:04:04 kurt Exp $ */
/* syncprov.c - syncrepl provider */
/* This work is part of OpenLDAP Software .
*
- * Copyright 2004 The OpenLDAP Foundation.
+ * Copyright 2004-2005 The OpenLDAP Foundation.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -56,7 +56,6 @@ typedef struct syncops {
struct berval s_base; /* ndn of search base */
ID s_eid; /* entryID of search base */
Operation *s_op; /* search op */
- int s_sid;
int s_rid;
struct berval s_filterstr;
int s_flags; /* search status */
@@ -84,6 +83,7 @@ typedef struct sync_control {
#define SLAP_SYNC_REFRESH_AND_PERSIST (LDAP_SYNC_REFRESH_AND_PERSIST<sr_entry->e_attrs,
slap_schema.si_ad_entryCSN );
- if ( a && ber_bvcmp( &a->a_vals[0], maxcsn )) {
+ if ( a && ber_bvcmp( &a->a_vals[0], maxcsn ) > 0 ) {
maxcsn->bv_len = a->a_vals[0].bv_len;
strcpy( maxcsn->bv_val, a->a_vals[0].bv_val );
}
@@ -609,12 +607,12 @@ syncprov_findcsn( Operation *op, int mod
AttributeAssertion eq;
int i, rc = LDAP_SUCCESS;
fpres_cookie pcookie;
- sync_control *srs;
+ sync_control *srs = NULL;
if ( mode != FIND_MAXCSN ) {
srs = op->o_controls[slap_cids.sc_LDAPsync];
- if ( srs->sr_state.ctxcsn->bv_len >= LDAP_LUTIL_CSNSTR_BUFSIZE ) {
+ if ( srs->sr_state.ctxcsn.bv_len >= LDAP_LUTIL_CSNSTR_BUFSIZE ) {
return LDAP_OTHER;
}
}
@@ -644,12 +642,13 @@ syncprov_findcsn( Operation *op, int mod
fop.ors_slimit = SLAP_NO_LIMIT;
cb.sc_private = &maxcsn;
cb.sc_response = findmax_cb;
+ strcpy( cbuf, si->si_ctxcsn.bv_val );
maxcsn.bv_val = cbuf;
- maxcsn.bv_len = 0;
+ maxcsn.bv_len = si->si_ctxcsn.bv_len;
break;
case FIND_CSN:
cf.f_choice = LDAP_FILTER_LE;
- cf.f_av_value = *srs->sr_state.ctxcsn;
+ cf.f_av_value = srs->sr_state.ctxcsn;
fbuf.bv_len = sprintf( buf, "(entryCSN<=%s)",
cf.f_av_value.bv_val );
fop.ors_attrsonly = 1;
@@ -663,7 +662,7 @@ syncprov_findcsn( Operation *op, int mod
af.f_next = NULL;
af.f_and = &cf;
cf.f_choice = LDAP_FILTER_LE;
- cf.f_av_value = *srs->sr_state.ctxcsn;
+ cf.f_av_value = srs->sr_state.ctxcsn;
cf.f_next = op->ors_filter;
fop.ors_filter = ⁡
filter2bv_x( &fop, fop.ors_filter, &fop.ors_filterstr );
@@ -696,10 +695,8 @@ syncprov_findcsn( Operation *op, int mod
switch( mode ) {
case FIND_MAXCSN:
- if ( maxcsn.bv_len ) {
- strcpy( si->si_ctxcsnbuf, maxcsn.bv_val );
- si->si_ctxcsn.bv_len = maxcsn.bv_len;
- }
+ strcpy( si->si_ctxcsnbuf, maxcsn.bv_val );
+ si->si_ctxcsn.bv_len = maxcsn.bv_len;
break;
case FIND_CSN:
/* If matching CSN was not found, invalidate the context. */
@@ -771,8 +768,7 @@ syncprov_sendresp( Operation *op, opcook
}
ctrls[1] = NULL;
- slap_compose_sync_cookie( op, &cookie, &opc->sctxcsn,
- so->s_sid, so->s_rid );
+ slap_compose_sync_cookie( op, &cookie, &opc->sctxcsn, so->s_rid );
e_uuid.e_attrs = &a_uuid;
a_uuid.a_desc = slap_schema.si_ad_entryUUID;
@@ -829,12 +825,14 @@ syncprov_free_syncop( syncops *so )
return;
}
ldap_pvt_thread_mutex_unlock( &so->s_mutex );
- filter_free( so->s_op->ors_filter );
- for ( ga = so->s_op->o_groups; ga; ga=gnext ) {
- gnext = ga->ga_next;
- ch_free( ga );
+ if ( so->s_flags & PS_IS_DETACHED ) {
+ filter_free( so->s_op->ors_filter );
+ for ( ga = so->s_op->o_groups; ga; ga=gnext ) {
+ gnext = ga->ga_next;
+ ch_free( ga );
+ }
+ ch_free( so->s_op );
}
- ch_free( so->s_op );
ch_free( so->s_base.bv_val );
for ( sr=so->s_res; sr; sr=srnext ) {
srnext = sr->s_next;
@@ -847,15 +845,19 @@ syncprov_free_syncop( syncops *so )
static int
syncprov_drop_psearch( syncops *so, int lock )
{
- if ( lock )
- ldap_pvt_thread_mutex_lock( &so->s_op->o_conn->c_mutex );
- so->s_op->o_conn->c_n_ops_executing--;
- so->s_op->o_conn->c_n_ops_completed++;
- LDAP_STAILQ_REMOVE( &so->s_op->o_conn->c_ops, so->s_op, slap_op,
- o_next );
- if ( lock )
- ldap_pvt_thread_mutex_unlock( &so->s_op->o_conn->c_mutex );
+ if ( so->s_flags & PS_IS_DETACHED ) {
+ if ( lock )
+ ldap_pvt_thread_mutex_lock( &so->s_op->o_conn->c_mutex );
+ so->s_op->o_conn->c_n_ops_executing--;
+ so->s_op->o_conn->c_n_ops_completed++;
+ LDAP_STAILQ_REMOVE( &so->s_op->o_conn->c_ops, so->s_op, slap_op,
+ o_next );
+ if ( lock )
+ ldap_pvt_thread_mutex_unlock( &so->s_op->o_conn->c_mutex );
+ }
syncprov_free_syncop( so );
+
+ return 0;
}
static int
@@ -882,12 +884,7 @@ syncprov_op_abandon( Operation *op, Slap
rs->sr_err = LDAP_CANCELLED;
send_ldap_result( so->s_op, rs );
}
- /* Our cloned searches have no ctrls set.
- * we don't want to muck with real search ops
- * from the frontend.
- */
- if ( ! so->s_op->o_sync )
- syncprov_drop_psearch( so, 0 );
+ syncprov_drop_psearch( so, 0 );
}
return SLAP_CB_CONTINUE;
}
@@ -926,10 +923,6 @@ syncprov_matchops( Operation *op, opcook
e = op->ora_e;
}
- /* Never replicate these */
- if ( is_entry_syncConsumerSubentry( e )) {
- goto done;
- }
if ( saveit ) {
ber_dupbv_x( &opc->sdn, &e->e_name, op->o_tmpmemctx );
ber_dupbv_x( &opc->sndn, &e->e_nname, op->o_tmpmemctx );
@@ -1002,7 +995,7 @@ syncprov_matchops( Operation *op, opcook
done:
if ( op->o_tag != LDAP_REQ_ADD ) {
op->o_bd->bd_info = (BackendInfo *)on->on_info;
- be_entry_release_r( op, e );
+ be_entry_release_rw( op, e, 0 );
op->o_bd->bd_info = (BackendInfo *)on;
}
if ( freefdn ) {
@@ -1057,6 +1050,8 @@ syncprov_op_cleanup( Operation *op, Slap
op->o_tmpfree( opc->sdn.bv_val, op->o_tmpmemctx );
op->o_callback = cb->sc_next;
op->o_tmpfree(cb, op->o_tmpmemctx);
+
+ return 0;
}
static void
@@ -1098,7 +1093,8 @@ syncprov_add_slog( Operation *op, struct
sessionlog *sl;
slog_entry *se;
- for ( sl = si->si_logs; sl; sl=sl->sl_next ) {
+ sl = si->si_logs;
+ {
/* Allocate a record. UUIDs are not NUL-terminated. */
se = ch_malloc( sizeof( slog_entry ) + opc->suuid.bv_len +
csn->bv_len + 1 );
@@ -1194,6 +1190,10 @@ syncprov_playlog( Operation *op, SlapRep
ndel = i;
+ /* Zero out unused slots */
+ for ( i=ndel; i < num - nmods; i++ )
+ uuids[i].bv_len = 0;
+
/* Mods must be validated to see if they belong in this delete set.
*/
@@ -1294,6 +1294,13 @@ syncprov_op_response( Operation *op, Sla
}
}
+ /* Don't do any processing for consumer contextCSN updates */
+ if ( SLAP_SYNC_SHADOW( op->o_bd ) &&
+ op->o_msgid == SLAP_SYNC_UPDATE_MSGID ) {
+ ldap_pvt_thread_mutex_unlock( &si->si_csn_mutex );
+ return SLAP_CB_CONTINUE;
+ }
+
si->si_numops++;
if ( si->si_chkops || si->si_chktime ) {
int do_check=0;
@@ -1581,6 +1588,7 @@ syncprov_detach_op( Operation *op, synco
op->o_conn->c_n_ops_executing++;
op->o_conn->c_n_ops_completed--;
LDAP_STAILQ_INSERT_TAIL( &op->o_conn->c_ops, op2, o_next );
+ so->s_flags |= PS_IS_DETACHED;
ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex );
}
@@ -1604,11 +1612,12 @@ syncprov_search_response( Operation *op,
Debug( LDAP_DEBUG_ANY, "bogus referral in context\n",0,0,0 );
return SLAP_CB_CONTINUE;
}
- if ( srs->sr_state.ctxcsn ) {
+ if ( !BER_BVISNULL( &srs->sr_state.ctxcsn )) {
Attribute *a = attr_find( rs->sr_entry->e_attrs,
slap_schema.si_ad_entryCSN );
+
/* Don't send the ctx entry twice */
- if ( bvmatch( &a->a_nvals[0], srs->sr_state.ctxcsn ))
+ if ( a && bvmatch( &a->a_nvals[0], &srs->sr_state.ctxcsn ) )
return LDAP_SUCCESS;
}
rs->sr_ctrls = op->o_tmpalloc( sizeof(LDAPControl *)*2,
@@ -1621,7 +1630,7 @@ syncprov_search_response( Operation *op,
slap_compose_sync_cookie( op, &cookie,
&op->ors_filter->f_and->f_ava->aa_value,
- srs->sr_state.sid, srs->sr_state.rid );
+ srs->sr_state.rid );
/* Is this a regular refresh? */
if ( !ss->ss_so ) {
@@ -1667,7 +1676,7 @@ syncprov_search_response( Operation *op,
if ( e ) {
op->o_bd->bd_info = (BackendInfo *)on->on_info;
- be_entry_release_r( op, e );
+ be_entry_release_rw( op, e, 0 );
op->o_bd->bd_info = (BackendInfo *)on;
}
ch_free( sr );
@@ -1741,7 +1750,6 @@ syncprov_op_search( Operation *op, SlapR
sop = ch_malloc( sizeof( syncops ));
*sop = so;
ldap_pvt_thread_mutex_init( &sop->s_mutex );
- sop->s_sid = srs->sr_state.sid;
sop->s_rid = srs->sr_state.rid;
sop->s_inuse = 1;
@@ -1759,13 +1767,13 @@ syncprov_op_search( Operation *op, SlapR
ctxcsn.bv_val = csnbuf;
/* If we have a cookie, handle the PRESENT lookups */
- if ( srs->sr_state.ctxcsn ) {
+ if ( !BER_BVISNULL( &srs->sr_state.ctxcsn )) {
sessionlog *sl;
/* The cookie was validated when it was parsed, just use it */
/* If just Refreshing and nothing has changed, shortcut it */
- if ( bvmatch( srs->sr_state.ctxcsn, &ctxcsn )) {
+ if ( bvmatch( &srs->sr_state.ctxcsn, &ctxcsn )) {
nochange = 1;
if ( !(op->o_sync_mode & SLAP_SYNC_PERSIST) ) {
LDAPControl *ctrls[2];
@@ -1783,14 +1791,13 @@ syncprov_op_search( Operation *op, SlapR
goto shortcut;
}
/* Do we have a sessionlog for this search? */
- for ( sl=si->si_logs; sl; sl=sl->sl_next )
- if ( sl->sl_sid == srs->sr_state.sid ) break;
+ sl=si->si_logs;
if ( sl ) {
ldap_pvt_thread_mutex_lock( &sl->sl_mutex );
- if ( ber_bvcmp( srs->sr_state.ctxcsn, &sl->sl_mincsn ) >= 0 ) {
+ if ( ber_bvcmp( &srs->sr_state.ctxcsn, &sl->sl_mincsn ) >= 0 ) {
do_present = 0;
/* mutex is unlocked in playlog */
- syncprov_playlog( op, rs, sl, srs->sr_state.ctxcsn, &ctxcsn );
+ syncprov_playlog( op, rs, sl, &srs->sr_state.ctxcsn, &ctxcsn );
} else {
ldap_pvt_thread_mutex_unlock( &sl->sl_mutex );
}
@@ -1838,7 +1845,7 @@ shortcut:
fava->f_choice = LDAP_FILTER_GE;
fava->f_ava = op->o_tmpalloc( sizeof(AttributeAssertion), op->o_tmpmemctx );
fava->f_ava->aa_desc = slap_schema.si_ad_entryCSN;
- ber_dupbv_x( &fava->f_ava->aa_value, srs->sr_state.ctxcsn, op->o_tmpmemctx );
+ ber_dupbv_x( &fava->f_ava->aa_value, &srs->sr_state.ctxcsn, op->o_tmpmemctx );
}
fava->f_next = op->ors_filter;
op->ors_filter = fand;
@@ -1942,44 +1949,30 @@ syncprov_db_config(
} else if ( strcasecmp( argv[0], "syncprov-sessionlog" ) == 0 ) {
sessionlog *sl;
- int sid, size;
- if ( argc != 3 ) {
+ int size;
+ if ( argc != 2 ) {
fprintf( stderr, "%s: line %d: wrong number of arguments in "
- "\"syncprov-sessionlog \"\n", fname, lineno );
- return -1;
- }
- sid = atoi( argv[1] );
- if ( sid < 0 || sid > 999 ) {
- fprintf( stderr,
- "%s: line %d: session log id %d is out of range [0..999]\n",
- fname, lineno, sid );
+ "\"syncprov-sessionlog \"\n", fname, lineno );
return -1;
}
- size = atoi( argv[2] );
+ size = atoi( argv[1] );
if ( size < 0 ) {
fprintf( stderr,
"%s: line %d: session log size %d is negative\n",
fname, lineno, size );
return -1;
}
- for ( sl = si->si_logs; sl; sl=sl->sl_next ) {
- if ( sl->sl_sid == sid ) {
- sl->sl_size = size;
- break;
- }
- }
+ sl = si->si_logs;
if ( !sl ) {
sl = ch_malloc( sizeof( sessionlog ) + LDAP_LUTIL_CSNSTR_BUFSIZE );
sl->sl_mincsn.bv_val = (char *)(sl+1);
sl->sl_mincsn.bv_len = 0;
- sl->sl_sid = sid;
- sl->sl_size = size;
sl->sl_num = 0;
sl->sl_head = sl->sl_tail = NULL;
- sl->sl_next = si->si_logs;
ldap_pvt_thread_mutex_init( &sl->sl_mutex );
si->si_logs = sl;
}
+ sl->sl_size = size;
return 0;
}
@@ -2019,6 +2012,11 @@ syncprov_db_open(
Attribute *a;
int rc;
+ rc = overlay_register_control( be, LDAP_CONTROL_SYNC );
+ if ( rc ) {
+ return rc;
+ }
+
connection_fake_init( &conn, op, thrctx );
op->o_bd = be;
op->o_dn = be->be_rootdn;
@@ -2041,7 +2039,7 @@ syncprov_db_open(
si->si_ctxcsnbuf[si->si_ctxcsn.bv_len] = '\0';
strcpy( ctxcsnbuf, si->si_ctxcsnbuf );
}
- be_entry_release_r( op, e );
+ be_entry_release_rw( op, e, 0 );
op->o_bd->bd_info = (BackendInfo *)on;
op->o_req_dn = be->be_suffix[0];
op->o_req_ndn = be->be_nsuffix[0];
@@ -2224,7 +2222,7 @@ static int syncprov_parseCtrl (
sr = op->o_tmpcalloc( 1, sizeof(struct sync_control), op->o_tmpmemctx );
sr->sr_rhint = rhint;
if (!BER_BVISNULL(&cookie)) {
- ber_bvarray_add( &sr->sr_state.octet_str, &cookie );
+ ber_dupbv( &sr->sr_state.octet_str, &cookie );
slap_parse_sync_cookie( &sr->sr_state );
}