mirror of
https://git.openldap.org/openldap/openldap.git
synced 2026-01-09 08:23:35 -05:00
ITS#6716: Keep sessionlog sorted by csn, compare mincsn with head.
This commit is contained in:
parent
439030a16d
commit
b4aa8dc68c
1 changed files with 35 additions and 9 deletions
|
|
@ -113,7 +113,6 @@ typedef struct slog_entry {
|
|||
} slog_entry;
|
||||
|
||||
typedef struct sessionlog {
|
||||
struct berval sl_mincsn;
|
||||
int sl_num;
|
||||
int sl_size;
|
||||
slog_entry *sl_head;
|
||||
|
|
@ -1501,6 +1500,23 @@ syncprov_add_slog( Operation *op )
|
|||
|
||||
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. */
|
||||
se = ch_malloc( sizeof( slog_entry ) + opc->suuid.bv_len +
|
||||
op->o_csn.bv_len + 1 );
|
||||
|
|
@ -1519,17 +1535,29 @@ syncprov_add_slog( Operation *op )
|
|||
|
||||
ldap_pvt_thread_mutex_lock( &sl->sl_mutex );
|
||||
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 {
|
||||
sl->sl_head = se;
|
||||
sl->sl_tail = se;
|
||||
}
|
||||
sl->sl_tail = se;
|
||||
sl->sl_num++;
|
||||
while ( sl->sl_num > sl->sl_size ) {
|
||||
se = sl->sl_head;
|
||||
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 );
|
||||
sl->sl_num--;
|
||||
}
|
||||
|
|
@ -2566,7 +2594,7 @@ no_change: if ( !(op->o_sync_mode & SLAP_SYNC_PERSIST) ) {
|
|||
/* Are there any log entries, and is the consumer state
|
||||
* 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;
|
||||
/* mutex is unlocked in playlog */
|
||||
syncprov_playlog( op, rs, sl, srs, ctxcsn, numcsns, sids );
|
||||
|
|
@ -2908,9 +2936,7 @@ sp_cf_gen(ConfigArgs *c)
|
|||
}
|
||||
sl = si->si_logs;
|
||||
if ( !sl ) {
|
||||
sl = ch_malloc( sizeof( sessionlog ) + LDAP_PVT_CSNSTR_BUFSIZE );
|
||||
sl->sl_mincsn.bv_val = (char *)(sl+1);
|
||||
sl->sl_mincsn.bv_len = 0;
|
||||
sl = ch_malloc( sizeof( sessionlog ) );
|
||||
sl->sl_num = 0;
|
||||
sl->sl_head = sl->sl_tail = NULL;
|
||||
ldap_pvt_thread_mutex_init( &sl->sl_mutex );
|
||||
|
|
|
|||
Loading…
Reference in a new issue