version 1.147.2.78, 2010/12/12 04:11:53
|
version 1.147.2.82, 2011/01/04 18:25:20
|
Line 113 typedef struct slog_entry {
|
Line 113 typedef struct slog_entry {
|
} slog_entry; |
} slog_entry; |
|
|
typedef struct sessionlog { |
typedef struct sessionlog { |
struct berval sl_mincsn; |
|
int sl_num; |
int sl_num; |
int sl_size; |
int sl_size; |
slog_entry *sl_head; |
slog_entry *sl_head; |
Line 134 typedef struct syncprov_info_t {
|
Line 133 typedef struct syncprov_info_t {
|
int si_nopres; /* Skip present phase */ |
int si_nopres; /* Skip present phase */ |
int si_usehint; /* use reload hint */ |
int si_usehint; /* use reload hint */ |
int si_active; /* True if there are active mods */ |
int si_active; /* True if there are active mods */ |
|
int si_dirty; /* True if the context is dirty, i.e changes |
|
* have been made without updating the csn. */ |
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; |
Line 1498 syncprov_add_slog( Operation *op )
|
Line 1499 syncprov_add_slog( Operation *op )
|
|
|
sl = si->si_logs; |
sl = si->si_logs; |
{ |
{ |
|
if ( BER_BVISEMPTY( &op->o_csn ) ) { |
|
/* During the syncrepl refresh phase we can receive operations |
|
* without a csn. We cannot reliably determine the consumers |
|
* state with respect to such operations, so we ignore them and |
|
* wipe out anything in the log if we see them. |
|
*/ |
|
ldap_pvt_thread_mutex_lock( &sl->sl_mutex ); |
|
while ( se = sl->sl_head ) { |
|
sl->sl_head = se->se_next; |
|
ch_free( se ); |
|
} |
|
sl->sl_tail = NULL; |
|
sl->sl_num = 0; |
|
ldap_pvt_thread_mutex_unlock( &sl->sl_mutex ); |
|
return; |
|
} |
|
|
/* Allocate a record. UUIDs are not NUL-terminated. */ |
/* Allocate a record. UUIDs are not NUL-terminated. */ |
se = ch_malloc( sizeof( slog_entry ) + opc->suuid.bv_len + |
se = ch_malloc( sizeof( slog_entry ) + opc->suuid.bv_len + |
op->o_csn.bv_len + 1 ); |
op->o_csn.bv_len + 1 ); |
Line 1516 syncprov_add_slog( Operation *op )
|
Line 1534 syncprov_add_slog( Operation *op )
|
|
|
ldap_pvt_thread_mutex_lock( &sl->sl_mutex ); |
ldap_pvt_thread_mutex_lock( &sl->sl_mutex ); |
if ( sl->sl_head ) { |
if ( sl->sl_head ) { |
sl->sl_tail->se_next = se; |
/* Keep the list in csn order. */ |
|
if ( ber_bvcmp( &sl->sl_tail->se_csn, &se->se_csn ) <= 0 ) { |
|
sl->sl_tail->se_next = se; |
|
sl->sl_tail = se; |
|
} else { |
|
slog_entry **sep; |
|
|
|
for ( sep = &sl->sl_head; *sep; sep = &(*sep)->se_next ) { |
|
if ( ber_bvcmp( &se->se_csn, &(*sep)->se_csn ) < 0 ) { |
|
se->se_next = *sep; |
|
*sep = se; |
|
break; |
|
} |
|
} |
|
} |
} else { |
} else { |
sl->sl_head = se; |
sl->sl_head = se; |
|
sl->sl_tail = se; |
} |
} |
sl->sl_tail = se; |
|
sl->sl_num++; |
sl->sl_num++; |
while ( sl->sl_num > sl->sl_size ) { |
while ( sl->sl_num > sl->sl_size ) { |
se = sl->sl_head; |
se = sl->sl_head; |
sl->sl_head = se->se_next; |
sl->sl_head = se->se_next; |
strcpy( sl->sl_mincsn.bv_val, se->se_csn.bv_val ); |
|
sl->sl_mincsn.bv_len = se->se_csn.bv_len; |
|
ch_free( se ); |
ch_free( se ); |
sl->sl_num--; |
sl->sl_num--; |
} |
} |
Line 1812 syncprov_op_response( Operation *op, Sla
|
Line 1842 syncprov_op_response( Operation *op, Sla
|
csn_changed = 1; |
csn_changed = 1; |
} |
} |
} |
} |
|
if ( csn_changed ) |
|
si->si_dirty = 0; |
ldap_pvt_thread_rdwr_wunlock( &si->si_csn_rwlock ); |
ldap_pvt_thread_rdwr_wunlock( &si->si_csn_rwlock ); |
|
|
if ( csn_changed ) { |
if ( csn_changed ) { |
|
syncops *ss; |
ldap_pvt_thread_mutex_lock( &si->si_ops_mutex ); |
ldap_pvt_thread_mutex_lock( &si->si_ops_mutex ); |
have_psearches = ( si->si_ops != NULL ); |
for ( ss = si->si_ops; ss; ss = ss->s_next ) { |
ldap_pvt_thread_mutex_unlock( &si->si_ops_mutex ); |
if ( ss->s_op->o_abandon ) |
|
continue; |
if ( have_psearches ) { |
/* Send the updated csn to all syncrepl consumers, |
for ( sm = opc->smatches; sm; sm=sm->sm_next ) { |
* including the server from which it originated. |
if ( sm->sm_op->s_op->o_abandon ) |
* The syncrepl consumer and syncprov provider on |
continue; |
* the originating server may be configured to store |
syncprov_qresp( opc, sm->sm_op, LDAP_SYNC_NEW_COOKIE ); |
* their csn values in different entries. |
} |
*/ |
|
syncprov_qresp( opc, ss, LDAP_SYNC_NEW_COOKIE ); |
} |
} |
|
ldap_pvt_thread_mutex_unlock( &si->si_ops_mutex ); |
} |
} |
} else { |
} else { |
ldap_pvt_thread_rdwr_wunlock( &si->si_csn_rwlock ); |
ldap_pvt_thread_rdwr_wunlock( &si->si_csn_rwlock ); |
Line 1855 syncprov_op_response( Operation *op, Sla
|
Line 1890 syncprov_op_response( Operation *op, Sla
|
} |
} |
} |
} |
} |
} |
|
si->si_dirty = !csn_changed; |
ldap_pvt_thread_rdwr_wunlock( &si->si_csn_rwlock ); |
ldap_pvt_thread_rdwr_wunlock( &si->si_csn_rwlock ); |
|
|
if ( do_check ) { |
if ( do_check ) { |
Line 2373 syncprov_op_search( Operation *op, SlapR
|
Line 2409 syncprov_op_search( Operation *op, SlapR
|
BerVarray ctxcsn; |
BerVarray ctxcsn; |
int i, *sids, numcsns; |
int i, *sids, numcsns; |
struct berval mincsn; |
struct berval mincsn; |
|
int dirty = 0; |
|
|
if ( !(op->o_sync_mode & SLAP_SYNC_REFRESH) ) return SLAP_CB_CONTINUE; |
if ( !(op->o_sync_mode & SLAP_SYNC_REFRESH) ) return SLAP_CB_CONTINUE; |
|
|
Line 2448 syncprov_op_search( Operation *op, SlapR
|
Line 2485 syncprov_op_search( Operation *op, SlapR
|
ctxcsn = NULL; |
ctxcsn = NULL; |
sids = NULL; |
sids = NULL; |
} |
} |
|
dirty = si->si_dirty; |
ldap_pvt_thread_rdwr_runlock( &si->si_csn_rwlock ); |
ldap_pvt_thread_rdwr_runlock( &si->si_csn_rwlock ); |
|
|
/* If we have a cookie, handle the PRESENT lookups */ |
/* If we have a cookie, handle the PRESENT lookups */ |
Line 2527 bailout:
|
Line 2565 bailout:
|
if ( changed ) |
if ( changed ) |
break; |
break; |
} |
} |
if ( !changed ) { |
if ( !changed && !dirty ) { |
do_present = 0; |
do_present = 0; |
no_change: if ( !(op->o_sync_mode & SLAP_SYNC_PERSIST) ) { |
no_change: if ( !(op->o_sync_mode & SLAP_SYNC_PERSIST) ) { |
LDAPControl *ctrls[2]; |
LDAPControl *ctrls[2]; |
Line 2555 no_change: if ( !(op->o_sync_mode & SLA
|
Line 2593 no_change: if ( !(op->o_sync_mode & SLA
|
/* Are there any log entries, and is the consumer state |
/* Are there any log entries, and is the consumer state |
* present in the session log? |
* present in the session log? |
*/ |
*/ |
if ( sl->sl_num > 0 && ber_bvcmp( &mincsn, &sl->sl_mincsn ) >= 0 ) { |
if ( sl->sl_num > 0 && ber_bvcmp( &mincsn, &sl->sl_head->se_csn ) >= 0 ) { |
do_present = 0; |
do_present = 0; |
/* mutex is unlocked in playlog */ |
/* mutex is unlocked in playlog */ |
syncprov_playlog( op, rs, sl, srs, ctxcsn, numcsns, sids ); |
syncprov_playlog( op, rs, sl, srs, ctxcsn, numcsns, sids ); |
Line 2611 shortcut:
|
Line 2649 shortcut:
|
} |
} |
|
|
/* If something changed, find the changes */ |
/* If something changed, find the changes */ |
if ( gotstate && changed ) { |
if ( gotstate && ( changed || dirty ) ) { |
Filter *fand, *fava; |
Filter *fand, *fava; |
|
|
fand = op->o_tmpalloc( sizeof(Filter), op->o_tmpmemctx ); |
fand = op->o_tmpalloc( sizeof(Filter), op->o_tmpmemctx ); |
Line 2656 shortcut:
|
Line 2694 shortcut:
|
* the refresh phase, just invoke the response callback to transition |
* the refresh phase, just invoke the response callback to transition |
* us into persist phase |
* us into persist phase |
*/ |
*/ |
if ( !changed ) { |
if ( !changed && !dirty ) { |
rs->sr_err = LDAP_SUCCESS; |
rs->sr_err = LDAP_SUCCESS; |
rs->sr_nentries = 0; |
rs->sr_nentries = 0; |
send_ldap_result( op, rs ); |
send_ldap_result( op, rs ); |
Line 2897 sp_cf_gen(ConfigArgs *c)
|
Line 2935 sp_cf_gen(ConfigArgs *c)
|
} |
} |
sl = si->si_logs; |
sl = si->si_logs; |
if ( !sl ) { |
if ( !sl ) { |
sl = ch_malloc( sizeof( sessionlog ) + LDAP_PVT_CSNSTR_BUFSIZE ); |
sl = ch_malloc( sizeof( sessionlog ) ); |
sl->sl_mincsn.bv_val = (char *)(sl+1); |
|
sl->sl_mincsn.bv_len = 0; |
|
sl->sl_num = 0; |
sl->sl_num = 0; |
sl->sl_head = sl->sl_tail = NULL; |
sl->sl_head = sl->sl_tail = NULL; |
ldap_pvt_thread_mutex_init( &sl->sl_mutex ); |
ldap_pvt_thread_mutex_init( &sl->sl_mutex ); |
Line 3116 syncprov_db_destroy(
|
Line 3152 syncprov_db_destroy(
|
se = se_next; |
se = se_next; |
} |
} |
|
|
|
ldap_pvt_thread_mutex_destroy(&si->si_logs->sl_mutex); |
ch_free( si->si_logs ); |
ch_free( si->si_logs ); |
} |
} |
if ( si->si_ctxcsn ) |
if ( si->si_ctxcsn ) |