typedef struct cookie_state {
ldap_pvt_thread_mutex_t cs_mutex;
+ ldap_pvt_thread_cond_t cs_cond;
struct berval *cs_vals;
int *cs_sids;
int cs_num;
int cs_age;
int cs_ref;
+ int cs_updating;
/* pending changes, not yet committed */
ldap_pvt_thread_mutex_t cs_pmutex;
struct berval ls_newRdn;
struct berval ls_delRdn;
struct berval ls_newSup;
+ struct berval ls_controls;
} logschema;
static logschema changelog_sc = {
BER_BVC("changes"),
BER_BVC("newRDN"),
BER_BVC("deleteOldRDN"),
- BER_BVC("newSuperior")
+ BER_BVC("newSuperior"),
+ BER_BVC("controls")
};
static logschema accesslog_sc = {
BER_BVC("reqMod"),
BER_BVC("reqNewRDN"),
BER_BVC("reqDeleteOldRDN"),
- BER_BVC("reqNewSuperior")
+ BER_BVC("reqNewSuperior"),
+ BER_BVC("reqControls")
};
static const char *
int rc;
int rhint;
char *base;
- char **attrs, *lattrs[8];
+ char **attrs, *lattrs[9];
char *filter;
int attrsonly;
int scope;
lattrs[3] = ls->ls_newRdn.bv_val;
lattrs[4] = ls->ls_delRdn.bv_val;
lattrs[5] = ls->ls_newSup.bv_val;
- lattrs[6] = slap_schema.si_ad_entryCSN->ad_cname.bv_val;
- lattrs[7] = NULL;
+ lattrs[6] = ls->ls_controls.bv_val;
+ lattrs[7] = slap_schema.si_ad_entryCSN->ad_cname.bv_val;
+ lattrs[8] = NULL;
rhint = 0;
base = si->si_logbase.bv_val;
}
} else if ( !ber_bvstrcasecmp( &bv, &ls->ls_newSup ) ) {
sup = bvals[0];
+ } else if ( !ber_bvstrcasecmp( &bv, &ls->ls_controls ) ) {
+ int i;
+ struct berval rel_ctrl_bv;
+
+ (void)ber_str2bv( "{" LDAP_CONTROL_RELAX, 0, 0, &rel_ctrl_bv );
+ for ( i = 0; bvals[i].bv_val; i++ ) {
+ struct berval cbv, tmp;
+
+ ber_bvchr_post( &cbv, &bvals[i], '}' );
+ ber_bvchr_post( &tmp, &cbv, '{' );
+ ber_bvchr_pre( &cbv, &tmp, ' ' );
+ if ( cbv.bv_len == tmp.bv_len ) /* control w/o value */
+ ber_bvchr_pre( &cbv, &tmp, '}' );
+ if ( !ber_bvcmp( &cbv, &rel_ctrl_bv ) )
+ op->o_relax = SLAP_CONTROL_CRITICAL;
+ }
} else if ( !ber_bvstrcasecmp( &bv,
&slap_schema.si_ad_entryCSN->ad_cname ) )
{
op->o_callback = &cb;
slap_op_time( &op->o_time, &op->o_tincr );
+ Debug( LDAP_DEBUG_SYNC, "syncrepl_message_to_op: %s tid %x\n",
+ si->si_ridtxt, op->o_tid, 0 );
+
switch( op->o_tag ) {
case LDAP_REQ_ADD:
case LDAP_REQ_MODIFY:
int freecsn = 1;
Debug( LDAP_DEBUG_SYNC,
- "syncrepl_entry: %s LDAP_RES_SEARCH_ENTRY(LDAP_SYNC_%s)\n",
- si->si_ridtxt, syncrepl_state2str( syncstate ), 0 );
+ "syncrepl_entry: %s LDAP_RES_SEARCH_ENTRY(LDAP_SYNC_%s) tid %x\n",
+ si->si_ridtxt, syncrepl_state2str( syncstate ), op->o_tid );
if (( syncstate == LDAP_SYNC_PRESENT || syncstate == LDAP_SYNC_ADD ) ) {
if ( !si->si_refreshPresent && !si->si_refreshDone ) {
mod.sml_next = NULL;
ldap_pvt_thread_mutex_lock( &si->si_cookieState->cs_mutex );
+ while ( si->si_cookieState->cs_updating )
+ ldap_pvt_thread_cond_wait( &si->si_cookieState->cs_cond, &si->si_cookieState->cs_mutex );
#ifdef CHECK_CSN
for ( i=0; i<syncCookie->numcsns; i++ ) {
ch_free( sc.sids );
return 0;
}
+
+ si->si_cookieState->cs_updating = 1;
+ ldap_pvt_thread_mutex_unlock( &si->si_cookieState->cs_mutex );
+
op->o_bd = si->si_wbe;
slap_queue_csn( op, &first );
op->orm_no_opattrs = 0;
op->o_dont_replicate = 0;
+ ldap_pvt_thread_mutex_lock( &si->si_cookieState->cs_mutex );
if ( rs_modify.sr_err == LDAP_SUCCESS ) {
slap_sync_cookie_free( &si->si_syncCookie, 0 );
}
#endif
+ si->si_cookieState->cs_updating = 0;
+ ldap_pvt_thread_cond_broadcast( &si->si_cookieState->cs_cond );
ldap_pvt_thread_mutex_unlock( &si->si_cookieState->cs_mutex );
op->o_bd = be;
if ( !sie->si_cookieState->cs_ref ) {
ch_free( sie->si_cookieState->cs_sids );
ber_bvarray_free( sie->si_cookieState->cs_vals );
+ ldap_pvt_thread_cond_destroy( &sie->si_cookieState->cs_cond );
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 );
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 );
+ ldap_pvt_thread_cond_init( &si->si_cookieState->cs_cond );
c->be->be_syncinfo = si;
}