[Date Prev][Date Next] [Chronological] [Thread] [Top]

(ITS#6716) syncprov sessionlog 'sl_mincsn' not assigned a value.



Full_Name: Chris Mikkelson
Version: 2.4.23
OS: FreeBSD
URL: ftp://ftp.openldap.org/incoming/
Submission from: (NULL) (204.147.85.37)


On line 2875 of servers/slapd/overlays/syncprov.c (release 2.4.23), the
sessionlog mincsn is initialized to a zero-length value.

                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->sl_num = 0;
                        sl->sl_head = sl->sl_tail = NULL;
                        ldap_pvt_thread_mutex_init( &sl->sl_mutex );
                        si->si_logs = sl;
                }

>From there, sl->sl_mincsn isn't touched until log entries are purged from the
sessionlog on line 1522:

                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--;
                }

So, after the sessionlog has its first entry recorded and before it has its
first entry received, sl->sl_mincsn is a zero-length value, which means the
following comparison on line 2536:

                        if ( sl->sl_num > 0 && ber_bvcmp( &mincsn,
&sl->sl_mincsn ) >= 0 ) {
                                do_present = 0;

will evaluate to true in cases where it should not. A quick fix would be to
compare directly against the CSN of the sessionlog's head:

--- syncprov.c.orig     2010-11-17 14:07:26.000000000 -0600
+++ syncprov.c  2010-11-19 16:50:58.000000000 -0600
@@ -2533,7 +2533,7 @@
                        /* 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 );