version 1.56.2.43, 2007/06/08 07:08:39
|
version 1.169, 2007/01/25 03:10:57
|
Line 1
|
Line 1
|
/* $OpenLDAP$ */ |
/* $OpenLDAP: pkg/ldap/servers/slapd/overlays/syncprov.c,v 1.168 2007/01/25 03:10:18 hyc Exp $ */ |
/* syncprov.c - syncrepl provider */ |
/* syncprov.c - syncrepl provider */ |
/* This work is part of OpenLDAP Software <http://www.openldap.org/>. |
/* This work is part of OpenLDAP Software <http://www.openldap.org/>. |
* |
* |
Line 127 typedef struct syncprov_info_t {
|
Line 127 typedef struct syncprov_info_t {
|
time_t si_chklast; /* time of last checkpoint */ |
time_t si_chklast; /* time of last checkpoint */ |
Avlnode *si_mods; /* entries being modified */ |
Avlnode *si_mods; /* entries being modified */ |
sessionlog *si_logs; |
sessionlog *si_logs; |
ldap_pvt_thread_rdwr_t si_csn_rwlock; |
ldap_pvt_thread_mutex_t si_csn_mutex; |
ldap_pvt_thread_mutex_t si_ops_mutex; |
ldap_pvt_thread_mutex_t si_ops_mutex; |
ldap_pvt_thread_mutex_t si_mods_mutex; |
ldap_pvt_thread_mutex_t si_mods_mutex; |
char si_ctxcsnbuf[LDAP_LUTIL_CSNSTR_BUFSIZE]; |
char si_ctxcsnbuf[LDAP_LUTIL_CSNSTR_BUFSIZE]; |
Line 843 syncprov_qplay( Operation *op, slap_over
|
Line 843 syncprov_qplay( Operation *op, slap_over
|
rc = be_entry_get_rw( op, &opc.sndn, NULL, NULL, 0, &e ); |
rc = be_entry_get_rw( op, &opc.sndn, NULL, NULL, 0, &e ); |
if ( rc ) { |
if ( rc ) { |
Debug( LDAP_DEBUG_SYNC, "syncprov_qplay: failed to get %s, " |
Debug( LDAP_DEBUG_SYNC, "syncprov_qplay: failed to get %s, " |
"error (%d), ignoring...\n", opc.sndn.bv_val, rc, 0 ); |
"error (%d), ignoring...\n", opc.sndn.bv_val, rc ); |
ch_free( sr ); |
ch_free( sr ); |
rc = 0; |
rc = 0; |
continue; |
continue; |
Line 911 syncprov_qtask( void *ctx, void *arg )
|
Line 911 syncprov_qtask( void *ctx, void *arg )
|
} |
} |
ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex ); |
ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex ); |
|
|
|
#if 0 /* FIXME: connection_close isn't exported from slapd. |
|
* should it be? |
|
*/ |
|
if ( rc ) { |
|
ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex ); |
|
if ( connection_state_closing( op->o_conn )) { |
|
connection_close( op->o_conn ); |
|
} |
|
ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex ); |
|
} |
|
#endif |
return NULL; |
return NULL; |
} |
} |
|
|
Line 1245 syncprov_op_cleanup( Operation *op, Slap
|
Line 1256 syncprov_op_cleanup( Operation *op, Slap
|
} |
} |
|
|
static void |
static void |
syncprov_checkpoint( Operation *op, SlapReply *rs, slap_overinst *on ) |
syncprov_checkpoint( Operation *op, SlapReply *rs, slap_overinst *on, |
|
struct berval *csn ) |
{ |
{ |
syncprov_info_t *si = on->on_bi.bi_private; |
|
Modifications mod; |
Modifications mod; |
Operation opm; |
Operation opm; |
SlapReply rsm = { 0 }; |
SlapReply rsm = { 0 }; |
Line 1255 syncprov_checkpoint( Operation *op, Slap
|
Line 1266 syncprov_checkpoint( Operation *op, Slap
|
slap_callback cb = {0}; |
slap_callback cb = {0}; |
|
|
/* If ctxcsn is empty, delete it */ |
/* If ctxcsn is empty, delete it */ |
if ( BER_BVISEMPTY( &si->si_ctxcsn )) { |
if ( BER_BVISEMPTY( csn )) { |
mod.sml_values = NULL; |
mod.sml_values = NULL; |
} else { |
} else { |
mod.sml_values = bv; |
mod.sml_values = bv; |
bv[1].bv_val = NULL; |
bv[1].bv_val = NULL; |
bv[0] = si->si_ctxcsn; |
bv[0] = *csn; |
} |
} |
mod.sml_nvalues = NULL; |
mod.sml_nvalues = NULL; |
mod.sml_desc = slap_schema.si_ad_contextCSN; |
mod.sml_desc = slap_schema.si_ad_contextCSN; |
Line 1373 syncprov_playlog( Operation *op, SlapRep
|
Line 1384 syncprov_playlog( Operation *op, SlapRep
|
* and everything else at the end. Do this first so we can |
* and everything else at the end. Do this first so we can |
* unlock the list mutex. |
* unlock the list mutex. |
*/ |
*/ |
Debug( LDAP_DEBUG_SYNC, "srs csn %s\n", srs->sr_state.ctxcsn.bv_val, 0, 0 ); |
Debug( LDAP_DEBUG_SYNC, "srs csn %s\n", srs-> sr_state.ctxcsn.bv_val, 0, 0 ); |
for ( se=sl->sl_head; se; se=se->se_next ) { |
for ( se=sl->sl_head; se; se=se->se_next ) { |
Debug( LDAP_DEBUG_SYNC, "log csn %s\n", se->se_csn.bv_val, 0, 0 ); |
Debug( LDAP_DEBUG_SYNC, "log csn %s\n", se-> se_csn.bv_val, |
ndel = ber_bvcmp( &se->se_csn, &srs->sr_state.ctxcsn ); |
0, 0 ); |
if ( ndel <= 0 ) { |
ndel = ber_bvcmp( &se->se_csn, &srs->sr_state.ctxcsn ); |
Debug( LDAP_DEBUG_SYNC, "cmp %d, too old\n", ndel, 0, 0 ); |
if ( ndel <= 0 ) { |
continue; |
Debug( LDAP_DEBUG_SYNC, "cmp %d, too old\n", ndel, |
} |
0, 0 ); |
ndel = ber_bvcmp( &se->se_csn, ctxcsn ); |
continue; |
if ( ndel > 0 ) { |
} |
Debug( LDAP_DEBUG_SYNC, "cmp %d, too new\n", ndel, 0, 0 ); |
ndel = ber_bvcmp( &se->se_csn, ctxcsn ); |
break; |
if ( ndel > 0 ) { |
} |
Debug( LDAP_DEBUG_SYNC, "cmp %d, too new\n", ndel, |
|
0, 0 ); |
|
break; |
|
} |
if ( se->se_tag == LDAP_REQ_DELETE ) { |
if ( se->se_tag == LDAP_REQ_DELETE ) { |
j = i; |
j = i; |
i++; |
i++; |
Line 1505 syncprov_op_response( Operation *op, Sla
|
Line 1519 syncprov_op_response( Operation *op, Sla
|
{ |
{ |
struct berval maxcsn = BER_BVNULL; |
struct berval maxcsn = BER_BVNULL; |
char cbuf[LDAP_LUTIL_CSNSTR_BUFSIZE]; |
char cbuf[LDAP_LUTIL_CSNSTR_BUFSIZE]; |
int do_check=0; |
int do_check = 0; |
|
|
/* Update our context CSN */ |
/* Update our context CSN */ |
cbuf[0] = '\0'; |
cbuf[0] = '\0'; |
ldap_pvt_thread_rdwr_wlock( &si->si_csn_rwlock ); |
ldap_pvt_thread_mutex_lock( &si->si_csn_mutex ); |
slap_get_commit_csn( op, &maxcsn ); |
slap_get_commit_csn( op, &maxcsn ); |
if ( !BER_BVISNULL( &maxcsn ) ) { |
if ( !BER_BVISNULL( &maxcsn ) ) { |
strcpy( cbuf, maxcsn.bv_val ); |
strcpy( cbuf, maxcsn.bv_val ); |
Line 1522 syncprov_op_response( Operation *op, Sla
|
Line 1536 syncprov_op_response( Operation *op, Sla
|
/* Don't do any processing for consumer contextCSN updates */ |
/* Don't do any processing for consumer contextCSN updates */ |
if ( SLAP_SYNC_SHADOW( op->o_bd ) && |
if ( SLAP_SYNC_SHADOW( op->o_bd ) && |
op->o_msgid == SLAP_SYNC_UPDATE_MSGID ) { |
op->o_msgid == SLAP_SYNC_UPDATE_MSGID ) { |
ldap_pvt_thread_rdwr_wunlock( &si->si_csn_rwlock ); |
ldap_pvt_thread_mutex_unlock( &si->si_csn_mutex ); |
return SLAP_CB_CONTINUE; |
return SLAP_CB_CONTINUE; |
} |
} |
|
|
Line 1538 syncprov_op_response( Operation *op, Sla
|
Line 1552 syncprov_op_response( Operation *op, Sla
|
si->si_chklast = op->o_time; |
si->si_chklast = op->o_time; |
} |
} |
} |
} |
ldap_pvt_thread_rdwr_wunlock( &si->si_csn_rwlock ); |
ldap_pvt_thread_mutex_unlock( &si->si_csn_mutex ); |
|
|
if ( do_check ) { |
|
ldap_pvt_thread_rdwr_rlock( &si->si_csn_rwlock ); |
|
syncprov_checkpoint( op, rs, on ); |
|
ldap_pvt_thread_rdwr_runlock( &si->si_csn_rwlock ); |
|
} |
|
|
|
opc->sctxcsn.bv_len = maxcsn.bv_len; |
opc->sctxcsn.bv_len = maxcsn.bv_len; |
opc->sctxcsn.bv_val = cbuf; |
opc->sctxcsn.bv_val = cbuf; |
|
|
|
if ( do_check ) { |
|
syncprov_checkpoint( op, rs, on, &opc->sctxcsn ); |
|
} |
|
|
/* Handle any persistent searches */ |
/* Handle any persistent searches */ |
if ( si->si_ops ) { |
if ( si->si_ops ) { |
switch(op->o_tag) { |
switch(op->o_tag) { |
Line 1608 syncprov_op_compare( Operation *op, Slap
|
Line 1620 syncprov_op_compare( Operation *op, Slap
|
a.a_vals = bv; |
a.a_vals = bv; |
a.a_nvals = a.a_vals; |
a.a_nvals = a.a_vals; |
|
|
ldap_pvt_thread_rdwr_rlock( &si->si_csn_rwlock ); |
ldap_pvt_thread_mutex_lock( &si->si_csn_mutex ); |
|
|
rs->sr_err = access_allowed( op, &e, op->oq_compare.rs_ava->aa_desc, |
rs->sr_err = access_allowed( op, &e, op->oq_compare.rs_ava->aa_desc, |
&op->oq_compare.rs_ava->aa_value, ACL_COMPARE, NULL ); |
&op->oq_compare.rs_ava->aa_value, ACL_COMPARE, NULL ); |
Line 1637 syncprov_op_compare( Operation *op, Slap
|
Line 1649 syncprov_op_compare( Operation *op, Slap
|
|
|
return_results:; |
return_results:; |
|
|
ldap_pvt_thread_rdwr_runlock( &si->si_csn_rwlock ); |
ldap_pvt_thread_mutex_unlock( &si->si_csn_mutex ); |
|
|
send_ldap_result( op, rs ); |
send_ldap_result( op, rs ); |
|
|
Line 1997 syncprov_op_search( Operation *op, SlapR
|
Line 2009 syncprov_op_search( Operation *op, SlapR
|
} |
} |
|
|
/* snapshot the ctxcsn */ |
/* snapshot the ctxcsn */ |
ldap_pvt_thread_rdwr_rlock( &si->si_csn_rwlock ); |
ldap_pvt_thread_mutex_lock( &si->si_csn_mutex ); |
strcpy( csnbuf, si->si_ctxcsnbuf ); |
strcpy( csnbuf, si->si_ctxcsnbuf ); |
ctxcsn.bv_len = si->si_ctxcsn.bv_len; |
ctxcsn.bv_len = si->si_ctxcsn.bv_len; |
ldap_pvt_thread_rdwr_runlock( &si->si_csn_rwlock ); |
ldap_pvt_thread_mutex_unlock( &si->si_csn_mutex ); |
ctxcsn.bv_val = csnbuf; |
ctxcsn.bv_val = csnbuf; |
|
|
/* If we have a cookie, handle the PRESENT lookups */ |
/* If we have a cookie, handle the PRESENT lookups */ |
Line 2147 syncprov_operational(
|
Line 2159 syncprov_operational(
|
if ( !a ) { |
if ( !a ) { |
for ( ap = &rs->sr_operational_attrs; *ap; ap=&(*ap)->a_next ); |
for ( ap = &rs->sr_operational_attrs; *ap; ap=&(*ap)->a_next ); |
|
|
a = ch_malloc( sizeof(Attribute)); |
a = attr_alloc( slap_schema.si_ad_contextCSN ); |
a->a_desc = slap_schema.si_ad_contextCSN; |
|
a->a_vals = ch_malloc( 2 * sizeof(struct berval)); |
a->a_vals = ch_malloc( 2 * sizeof(struct berval)); |
a->a_vals[1].bv_val = NULL; |
a->a_vals[1].bv_val = NULL; |
a->a_nvals = a->a_vals; |
a->a_nvals = a->a_vals; |
a->a_next = NULL; |
|
a->a_flags = 0; |
|
*ap = a; |
*ap = a; |
} |
} |
|
|
ldap_pvt_thread_rdwr_rlock( &si->si_csn_rwlock ); |
ldap_pvt_thread_mutex_lock( &si->si_csn_mutex ); |
if ( !ap ) { |
if ( !ap ) { |
strcpy( a->a_vals[0].bv_val, si->si_ctxcsnbuf ); |
strcpy( a->a_vals[0].bv_val, si->si_ctxcsnbuf ); |
} else { |
} else { |
ber_dupbv( &a->a_vals[0], &si->si_ctxcsn ); |
ber_dupbv( &a->a_vals[0], &si->si_ctxcsn ); |
} |
} |
ldap_pvt_thread_rdwr_runlock( &si->si_csn_rwlock ); |
ldap_pvt_thread_mutex_unlock( &si->si_csn_mutex ); |
} |
} |
} |
} |
return SLAP_CB_CONTINUE; |
return SLAP_CB_CONTINUE; |
Line 2477 syncprov_db_close(
|
Line 2486 syncprov_db_close(
|
op->o_bd = be; |
op->o_bd = be; |
op->o_dn = be->be_rootdn; |
op->o_dn = be->be_rootdn; |
op->o_ndn = be->be_rootndn; |
op->o_ndn = be->be_rootndn; |
syncprov_checkpoint( op, &rs, on ); |
syncprov_checkpoint( op, &rs, on, &si->si_ctxcsn ); |
} |
} |
|
|
return 0; |
return 0; |
Line 2500 syncprov_db_init(
|
Line 2509 syncprov_db_init(
|
|
|
si = ch_calloc(1, sizeof(syncprov_info_t)); |
si = ch_calloc(1, sizeof(syncprov_info_t)); |
on->on_bi.bi_private = si; |
on->on_bi.bi_private = si; |
ldap_pvt_thread_rdwr_init( &si->si_csn_rwlock ); |
ldap_pvt_thread_mutex_init( &si->si_csn_mutex ); |
ldap_pvt_thread_mutex_init( &si->si_ops_mutex ); |
ldap_pvt_thread_mutex_init( &si->si_ops_mutex ); |
ldap_pvt_thread_mutex_init( &si->si_mods_mutex ); |
ldap_pvt_thread_mutex_init( &si->si_mods_mutex ); |
si->si_ctxcsn.bv_val = si->si_ctxcsnbuf; |
si->si_ctxcsn.bv_val = si->si_ctxcsnbuf; |
Line 2538 syncprov_db_destroy(
|
Line 2547 syncprov_db_destroy(
|
} |
} |
ldap_pvt_thread_mutex_destroy( &si->si_mods_mutex ); |
ldap_pvt_thread_mutex_destroy( &si->si_mods_mutex ); |
ldap_pvt_thread_mutex_destroy( &si->si_ops_mutex ); |
ldap_pvt_thread_mutex_destroy( &si->si_ops_mutex ); |
ldap_pvt_thread_rdwr_destroy( &si->si_csn_rwlock ); |
ldap_pvt_thread_mutex_destroy( &si->si_csn_mutex ); |
ch_free( si ); |
ch_free( si ); |
} |
} |
|
|
Line 2628 static int syncprov_parseCtrl (
|
Line 2637 static int syncprov_parseCtrl (
|
sr->sr_rhint = rhint; |
sr->sr_rhint = rhint; |
if (!BER_BVISNULL(&cookie)) { |
if (!BER_BVISNULL(&cookie)) { |
ber_dupbv_x( &sr->sr_state.octet_str, &cookie, op->o_tmpmemctx ); |
ber_dupbv_x( &sr->sr_state.octet_str, &cookie, op->o_tmpmemctx ); |
if ( slap_parse_sync_cookie( &sr->sr_state, op->o_tmpmemctx ) || |
slap_parse_sync_cookie( &sr->sr_state, op->o_tmpmemctx ); |
sr->sr_state.rid == -1 ) { |
if ( sr->sr_state.rid == -1 ) { |
rs->sr_text = "Sync control : cookie parsing error"; |
rs->sr_text = "Sync control : cookie parsing error"; |
return LDAP_PROTOCOL_ERROR; |
return LDAP_PROTOCOL_ERROR; |
} |
} |