version 1.302, 2009/11/21 10:54:59
|
version 1.303, 2009/11/22 03:42:00
|
Line 1
|
Line 1
|
/* $OpenLDAP: pkg/ldap/servers/slapd/overlays/syncprov.c,v 1.301 2009/11/21 10:43:01 hyc Exp $ */ |
/* $OpenLDAP: pkg/ldap/servers/slapd/overlays/syncprov.c,v 1.302 2009/11/21 10:54:59 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 48 typedef struct modtarget {
|
Line 48 typedef struct modtarget {
|
/* A queued result of a persistent search */ |
/* A queued result of a persistent search */ |
typedef struct syncres { |
typedef struct syncres { |
struct syncres *s_next; |
struct syncres *s_next; |
|
Entry *s_e; |
struct berval s_dn; |
struct berval s_dn; |
struct berval s_ndn; |
struct berval s_ndn; |
struct berval s_uuid; |
struct berval s_uuid; |
Line 145 typedef struct opcookie {
|
Line 146 typedef struct opcookie {
|
slap_overinst *son; |
slap_overinst *son; |
syncmatches *smatches; |
syncmatches *smatches; |
modtarget *smt; |
modtarget *smt; |
|
Entry *se; |
struct berval sdn; /* DN of entry, for deletes */ |
struct berval sdn; /* DN of entry, for deletes */ |
struct berval sndn; |
struct berval sndn; |
struct berval suuid; /* UUID of entry */ |
struct berval suuid; /* UUID of entry */ |
Line 154 typedef struct opcookie {
|
Line 156 typedef struct opcookie {
|
short sreference; /* Is the entry a reference? */ |
short sreference; /* Is the entry a reference? */ |
} opcookie; |
} opcookie; |
|
|
|
typedef struct mutexint { |
|
ldap_pvt_thread_mutex_t mi_mutex; |
|
int mi_int; |
|
} mutexint; |
|
|
typedef struct fbase_cookie { |
typedef struct fbase_cookie { |
struct berval *fdn; /* DN of a modified entry, for scope testing */ |
struct berval *fdn; /* DN of a modified entry, for scope testing */ |
syncops *fss; /* persistent search we're testing against */ |
syncops *fss; /* persistent search we're testing against */ |
Line 739 again:
|
Line 746 again:
|
return rc; |
return rc; |
} |
} |
|
|
|
/* Should find a place to cache these */ |
|
static mutexint *get_mutexint() |
|
{ |
|
mutexint *mi = ch_malloc( sizeof( mutexint )); |
|
ldap_pvt_thread_mutex_init( &mi->mi_mutex ); |
|
mi->mi_int = 1; |
|
return mi; |
|
} |
|
|
|
static void inc_mutexint( mutexint *mi ) |
|
{ |
|
ldap_pvt_thread_mutex_lock( &mi->mi_mutex ); |
|
mi->mi_int++; |
|
ldap_pvt_thread_mutex_unlock( &mi->mi_mutex ); |
|
} |
|
|
|
/* return resulting counter */ |
|
static int dec_mutexint( mutexint *mi ) |
|
{ |
|
int i; |
|
ldap_pvt_thread_mutex_lock( &mi->mi_mutex ); |
|
i = --mi->mi_int; |
|
ldap_pvt_thread_mutex_unlock( &mi->mi_mutex ); |
|
if ( !i ) { |
|
ldap_pvt_thread_mutex_destroy( &mi->mi_mutex ); |
|
ch_free( mi ); |
|
} |
|
return i; |
|
} |
|
|
static void |
static void |
syncprov_free_syncop( syncops *so ) |
syncprov_free_syncop( syncops *so ) |
{ |
{ |
Line 762 syncprov_free_syncop( syncops *so )
|
Line 799 syncprov_free_syncop( syncops *so )
|
ch_free( so->s_base.bv_val ); |
ch_free( so->s_base.bv_val ); |
for ( sr=so->s_res; sr; sr=srnext ) { |
for ( sr=so->s_res; sr; sr=srnext ) { |
srnext = sr->s_next; |
srnext = sr->s_next; |
|
if ( sr->s_e ) { |
|
if ( !dec_mutexint( sr->s_e->e_private )) { |
|
sr->s_e->e_private = NULL; |
|
entry_free( sr->s_e ); |
|
} |
|
} |
ch_free( sr ); |
ch_free( sr ); |
} |
} |
ldap_pvt_thread_mutex_destroy( &so->s_mutex ); |
ldap_pvt_thread_mutex_destroy( &so->s_mutex ); |
Line 770 syncprov_free_syncop( syncops *so )
|
Line 813 syncprov_free_syncop( syncops *so )
|
|
|
/* Send a persistent search response */ |
/* Send a persistent search response */ |
static int |
static int |
syncprov_sendresp( Operation *op, opcookie *opc, syncops *so, |
syncprov_sendresp( Operation *op, opcookie *opc, syncops *so, int mode ) |
Entry **e, int mode ) |
|
{ |
{ |
slap_overinst *on = opc->son; |
slap_overinst *on = opc->son; |
|
|
Line 811 syncprov_sendresp( Operation *op, opcook
|
Line 853 syncprov_sendresp( Operation *op, opcook
|
} |
} |
|
|
rs.sr_ctrls = ctrls; |
rs.sr_ctrls = ctrls; |
op->o_bd->bd_info = (BackendInfo *)on->on_info; |
|
switch( mode ) { |
switch( mode ) { |
case LDAP_SYNC_ADD: |
case LDAP_SYNC_ADD: |
rs.sr_entry = *e; |
rs.sr_entry = opc->se; |
if ( rs.sr_entry->e_private ) |
|
rs.sr_flags = REP_ENTRY_MUSTRELEASE; |
|
if ( opc->sreference && so->s_op->o_managedsait <= SLAP_CONTROL_IGNORED ) { |
if ( opc->sreference && so->s_op->o_managedsait <= SLAP_CONTROL_IGNORED ) { |
rs.sr_ref = get_entry_referrals( op, rs.sr_entry ); |
rs.sr_ref = get_entry_referrals( op, rs.sr_entry ); |
rs.sr_err = send_search_reference( op, &rs ); |
rs.sr_err = send_search_reference( op, &rs ); |
ber_bvarray_free( rs.sr_ref ); |
ber_bvarray_free( rs.sr_ref ); |
if ( !rs.sr_entry ) |
|
*e = NULL; |
|
break; |
break; |
} |
} |
/* fallthru */ |
/* fallthru */ |
case LDAP_SYNC_MODIFY: |
case LDAP_SYNC_MODIFY: |
rs.sr_entry = *e; |
rs.sr_entry = opc->se; |
if ( rs.sr_entry->e_private ) |
|
rs.sr_flags = REP_ENTRY_MUSTRELEASE; |
|
rs.sr_attrs = op->ors_attrs; |
rs.sr_attrs = op->ors_attrs; |
rs.sr_err = send_search_entry( op, &rs ); |
rs.sr_err = send_search_entry( op, &rs ); |
if ( !rs.sr_entry ) |
|
*e = NULL; |
|
break; |
break; |
case LDAP_SYNC_DELETE: |
case LDAP_SYNC_DELETE: |
e_uuid.e_attrs = NULL; |
e_uuid.e_attrs = NULL; |
Line 905 syncprov_qplay( Operation *op, syncops *
|
Line 938 syncprov_qplay( Operation *op, syncops *
|
opc.suuid = sr->s_uuid; |
opc.suuid = sr->s_uuid; |
opc.sctxcsn = sr->s_csn; |
opc.sctxcsn = sr->s_csn; |
opc.sreference = sr->s_isreference; |
opc.sreference = sr->s_isreference; |
e = NULL; |
opc.se = sr->s_e; |
|
|
if ( sr->s_mode != LDAP_SYNC_DELETE ) { |
rc = syncprov_sendresp( op, &opc, so, sr->s_mode ); |
rc = overlay_entry_get_ov( op, &opc.sndn, NULL, NULL, 0, &e, on ); |
|
if ( rc ) { |
|
Debug( LDAP_DEBUG_SYNC, "syncprov_qplay: failed to get %s, " |
|
"error (%d), ignoring...\n", opc.sndn.bv_val, rc, 0 ); |
|
ch_free( sr ); |
|
rc = 0; |
|
continue; |
|
} |
|
} |
|
rc = syncprov_sendresp( op, &opc, so, &e, sr->s_mode ); |
|
|
|
if ( e ) { |
if ( opc.se ) { |
overlay_entry_release_ov( op, e, 0, on ); |
if ( !dec_mutexint( opc.se->e_private )) { |
|
opc.se->e_private = NULL; |
|
entry_free ( opc.se ); |
|
} |
} |
} |
} |
} |
|
|
Line 1014 syncprov_qresp( opcookie *opc, syncops *
|
Line 1040 syncprov_qresp( opcookie *opc, syncops *
|
srsize += cookie.bv_len + 1; |
srsize += cookie.bv_len + 1; |
sr = ch_malloc( srsize ); |
sr = ch_malloc( srsize ); |
sr->s_next = NULL; |
sr->s_next = NULL; |
|
sr->s_e = opc->se; |
|
/* bump refcount on this entry */ |
|
if ( opc->se ) |
|
inc_mutexint( opc->se->e_private ); |
sr->s_dn.bv_val = (char *)(sr + 1); |
sr->s_dn.bv_val = (char *)(sr + 1); |
sr->s_dn.bv_len = opc->sdn.bv_len; |
sr->s_dn.bv_len = opc->sdn.bv_len; |
sr->s_mode = mode; |
sr->s_mode = mode; |
Line 1157 syncprov_matchops( Operation *op, opcook
|
Line 1187 syncprov_matchops( Operation *op, opcook
|
rc = overlay_entry_get_ov( op, fc.fdn, NULL, NULL, 0, &e, on ); |
rc = overlay_entry_get_ov( op, fc.fdn, NULL, NULL, 0, &e, on ); |
/* If we're sending responses now, make a copy and unlock the DB */ |
/* If we're sending responses now, make a copy and unlock the DB */ |
if ( e && !saveit ) { |
if ( e && !saveit ) { |
Entry *e2 = entry_dup( e ); |
if ( !opc->se ) { |
|
opc->se = entry_dup( e ); |
|
opc->se->e_private = get_mutexint(); |
|
} |
overlay_entry_release_ov( op, e, 0, on ); |
overlay_entry_release_ov( op, e, 0, on ); |
e = e2; |
e = opc->se; |
} |
} |
if ( rc ) { |
if ( rc ) { |
op->o_bd = b0; |
op->o_bd = b0; |
Line 1167 syncprov_matchops( Operation *op, opcook
|
Line 1200 syncprov_matchops( Operation *op, opcook
|
} |
} |
} else { |
} else { |
e = op->ora_e; |
e = op->ora_e; |
|
if ( !saveit ) { |
|
if ( !opc->se ) { |
|
opc->se = entry_dup( e ); |
|
opc->se->e_private = get_mutexint(); |
|
} |
|
e = opc->se; |
|
} |
} |
} |
|
|
if ( saveit || op->o_tag == LDAP_REQ_ADD ) { |
if ( saveit || op->o_tag == LDAP_REQ_ADD ) { |
Line 1227 syncprov_matchops( Operation *op, opcook
|
Line 1267 syncprov_matchops( Operation *op, opcook
|
continue; |
continue; |
} |
} |
|
|
|
|
/* If we're sending results now, look for this op in old matches */ |
/* If we're sending results now, look for this op in old matches */ |
if ( !saveit ) { |
if ( !saveit ) { |
syncmatches *old; |
syncmatches *old; |
Line 1299 syncprov_matchops( Operation *op, opcook
|
Line 1338 syncprov_matchops( Operation *op, opcook
|
if ( !SLAP_ISOVERLAY( op->o_bd )) { |
if ( !SLAP_ISOVERLAY( op->o_bd )) { |
op->o_bd = &db; |
op->o_bd = &db; |
} |
} |
overlay_entry_release_ov( op, e, 0, on ); |
if ( saveit ) |
|
overlay_entry_release_ov( op, e, 0, on ); |
op->o_bd = b0; |
op->o_bd = b0; |
} |
} |
|
if ( opc->se && !saveit ) { |
|
if ( !dec_mutexint( opc->se->e_private )) { |
|
opc->se->e_private = NULL; |
|
entry_free( opc->se ); |
|
opc->se = NULL; |
|
} |
|
} |
if ( freefdn ) { |
if ( freefdn ) { |
op->o_tmpfree( fc.fdn->bv_val, op->o_tmpmemctx ); |
op->o_tmpfree( fc.fdn->bv_val, op->o_tmpmemctx ); |
} |
} |