]> git.sur5r.net Git - openldap/commitdiff
ITS#6716
authorQuanah Gibson-Mount <quanah@openldap.org>
Tue, 4 Jan 2011 18:23:13 +0000 (18:23 +0000)
committerQuanah Gibson-Mount <quanah@openldap.org>
Tue, 4 Jan 2011 18:23:13 +0000 (18:23 +0000)
CHANGES
servers/slapd/overlays/syncprov.c

diff --git a/CHANGES b/CHANGES
index 35e864ffc44768543d521782353fc4a9ce248f93..903d51f6cd3ac51d60c258e26fbe49b1e9a785cf 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -68,6 +68,7 @@ OpenLDAP 2.4.24 Engineering
        Fixed slapo-syncprov active mod race (ITS#6709)
        Fixed slapo-syncprov to refresh if context is dirty (ITS#6710)
        Fixed slapo-syncprov CSN updates to all replicas (ITS#6718)
+       Fixed slapo-syncprov sessionlog ordering (ITS#6716)
        Fixed contrib/autogroup LDAP URI with attribute filter (ITS#6536)
        Fixed contrib/nssov to only close socket on shutdown (ITS#6676)
        Fixed contrib/nssov multi platform support (ITS#6604)
index c9b5e5bd25a11664a9ac2a27ef3402a9c4093aa8..42a21092942b9f49e61016571e9f212cb869f075 100644 (file)
@@ -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;
@@ -1500,6 +1499,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 );
@@ -1518,17 +1534,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--;
                }
@@ -2565,7 +2593,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 );
@@ -2907,9 +2935,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 );