]> git.sur5r.net Git - openldap/commitdiff
Support multiple sync replication at the consumer :
authorJong Hyuk Choi <jongchoi@openldap.org>
Wed, 26 Nov 2003 19:49:47 +0000 (19:49 +0000)
committerJong Hyuk Choi <jongchoi@openldap.org>
Wed, 26 Nov 2003 19:49:47 +0000 (19:49 +0000)
1) simultaneous operation of multiple active sync replication threads
2) cookie management for individual sync replication thread
   (include rid=%3d to the slapd cookie command line option (-c))

23 files changed:
doc/man/man5/slapd.conf.5
servers/slapd/add.c
servers/slapd/back-bdb/add.c
servers/slapd/back-bdb/ctxcsn.c
servers/slapd/back-bdb/delete.c
servers/slapd/back-bdb/modify.c
servers/slapd/back-bdb/modrdn.c
servers/slapd/back-bdb/search.c
servers/slapd/back-ldbm/delete.c
servers/slapd/back-ldbm/modify.c
servers/slapd/back-ldbm/modrdn.c
servers/slapd/backend.c
servers/slapd/config.c
servers/slapd/delete.c
servers/slapd/globals.c
servers/slapd/ldapsync.c
servers/slapd/main.c
servers/slapd/modify.c
servers/slapd/modrdn.c
servers/slapd/passwd.c
servers/slapd/proto-slap.h
servers/slapd/slap.h
servers/slapd/syncrepl.c

index 19ea3779d59e9d50901cc655e90f0732353f6647..f72efa9c6f40ed792d8674ee5fcfaa5b84c1b0a0 100644 (file)
@@ -1164,7 +1164,7 @@ replication engine.
 .B id
 identifies the current
 .B syncrepl
-directive within the database.
+directive within the replication consumer site.
 It is a non-negative integer having no more than three digits.
 .B provider
 specifies the replication provider site containing the master content
index 323fd00bdc989e18b25011e0e0d33fe5f0ce074e..84d73f9a5912b48296010d8f456d820ea4b06e18 100644 (file)
@@ -244,10 +244,10 @@ do_add( Operation *op, SlapReply *rs )
                /* do the update here */
                int repl_user = be_isupdate(op->o_bd, &op->o_ndn );
 #ifndef SLAPD_MULTIMASTER
-               if ( !op->o_bd->be_syncinfo &&
+               if ( LDAP_STAILQ_EMPTY( &op->o_bd->be_syncinfo ) &&
                        ( !op->o_bd->be_update_ndn.bv_len || repl_user ))
 #else
-               if ( !op->o_bd->be_syncinfo )
+               if ( LDAP_STAILQ_EMPTY( &op->o_bd->be_syncinfo ))
 #endif
                {
                        int update = op->o_bd->be_update_ndn.bv_len;
@@ -328,8 +328,13 @@ do_add( Operation *op, SlapReply *rs )
                        }
 #endif /* LDAP_SLAPI */
 
-                       if ( op->o_bd->be_syncinfo ) {
-                               defref = op->o_bd->be_syncinfo->si_provideruri_bv;
+                       if ( !LDAP_STAILQ_EMPTY( &op->o_bd->be_syncinfo )) {
+                               syncinfo_t *si;
+                               LDAP_STAILQ_FOREACH( si, &op->o_bd->be_syncinfo, si_next ) {
+                                       struct berval tmpbv;
+                                       ber_dupbv( &tmpbv, &si->si_provideruri_bv[0] );
+                                       ber_bvarray_add( &defref, &tmpbv );
+                               }
                        } else {
                                defref = op->o_bd->be_update_refs
                                        ? op->o_bd->be_update_refs : default_referral;
index bb6e2aeb2e1b4240a3f97ba65c3be40f8551ec38..f8cb4d6bd040e862cf550c8a21ae66d4d1ec2089 100644 (file)
@@ -436,7 +436,7 @@ retry:      /* transaction retry */
                goto return_results;
        }
 
-       if ( !op->o_bd->be_syncinfo ) {
+       if ( LDAP_STAILQ_EMPTY( &op->o_bd->be_syncinfo )) {
                rc = bdb_csn_commit( op, rs, ltid, ei, &suffix_ei,
                        &ctxcsn_e, &ctxcsn_added, locker );
                switch ( rc ) {
@@ -481,9 +481,10 @@ retry:     /* transaction retry */
                                suffix_ei = op->oq_add.rs_e->e_private;
                        }
 
-                       if ( !op->o_bd->be_syncinfo ) {
+                       if ( LDAP_STAILQ_EMPTY( &op->o_bd->be_syncinfo )) {
                                if ( ctxcsn_added ) {
-                                       bdb_cache_add( bdb, suffix_ei, ctxcsn_e, (struct berval *)&slap_ldapsync_cn_bv, locker );
+                                       bdb_cache_add( bdb, suffix_ei, ctxcsn_e,
+                                                       (struct berval *)&slap_ldapsync_cn_bv, locker );
                                }
                        }
 
index 6d9af8c80b686ee4a791159babfb88b7839ccf6e..f6e012d758adb0a0042c48022284f32c6464e82a 100644 (file)
@@ -263,20 +263,88 @@ bdb_get_commit_csn(
        int                     ctxcsn_added = 0;
        int                     rc;
        struct sync_cookie syncCookie = { NULL, -1, NULL};
+       syncinfo_t      *si;
 
-       if ( op->o_sync_mode != SLAP_SYNC_NONE ) {
-               if ( op->o_bd->be_syncinfo ) {
-                       char substr[67];
-                       struct berval bv;
-                       sprintf( substr, "cn=syncrepl%d", op->o_bd->be_syncinfo->si_id );
+       if ( op->o_sync_mode != SLAP_SYNC_NONE &&
+                !LDAP_STAILQ_EMPTY( &op->o_bd->be_syncinfo )) {
+               char substr[67];
+               struct berval bv;
+
+               LDAP_STAILQ_FOREACH( si, &op->o_bd->be_syncinfo, si_next ) {
+                       sprintf( substr, "cn=syncrepl%d", si->si_id );
                        ber_str2bv( substr, 0, 0, &bv );
                        build_new_dn( &ctxcsn_ndn, &op->o_bd->be_nsuffix[0], &bv, NULL );
-               } else {
-                       build_new_dn( &ctxcsn_ndn, &op->o_bd->be_nsuffix[0],
-                                               (struct berval *)&slap_ldapsync_cn_bv, NULL );
+
+consumer_ctxcsn_retry :
+                       rs->sr_err = bdb_dn2entry( op, NULL, &ctxcsn_ndn, &ctxcsn_ei,
+                                                                               0, locker, ctxcsn_lock );
+                       switch(rs->sr_err) {
+                       case 0:
+                               ch_free( ctxcsn_ndn.bv_val );
+                               ctxcsn_ndn.bv_val = NULL;
+                               if ( ctxcsn_ei ) {
+                                       ctxcsn_e = ctxcsn_ei->bei_e;
+                               }
+                               break;
+                       case LDAP_BUSY:
+                               ch_free( ctxcsn_ndn.bv_val );
+                               LOCK_ID_FREE (bdb->bi_dbenv, locker );
+                               return LDAP_BUSY;
+                       case DB_LOCK_DEADLOCK:
+                       case DB_LOCK_NOTGRANTED:
+                               goto consumer_ctxcsn_retry;
+                       case DB_NOTFOUND:
+                               ch_free( ctxcsn_ndn.bv_val );
+                               LOCK_ID_FREE( bdb->bi_dbenv, locker );
+                               return LDAP_OTHER;
+                       default:
+                               ch_free( ctxcsn_ndn.bv_val );
+                               ctxcsn_ndn.bv_val = NULL;
+                               LOCK_ID_FREE (bdb->bi_dbenv, locker );
+                               return LDAP_OTHER;
+                       }
+
+                       if ( ctxcsn_e ) {
+                               csn_a = attr_find( ctxcsn_e->e_attrs,
+                                                       slap_schema.si_ad_syncreplCookie );
+                               if ( csn_a ) {
+                                       struct berval cookie;
+                                       const char *text;
+                                       int match = -1;
+                                       ber_dupbv( &cookie, &csn_a->a_vals[0] );
+                                       ber_bvarray_add( &syncCookie.octet_str, &cookie );
+                                       slap_parse_sync_cookie( &syncCookie );
+                                       if ( *search_context_csn &&
+                                                (*search_context_csn)->bv_val != NULL ) {
+                                               value_match( &match, slap_schema.si_ad_entryCSN,
+                                                       slap_schema.si_ad_entryCSN->ad_type->sat_ordering,
+                                                       SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
+                                                       &syncCookie.ctxcsn, *search_context_csn, &text );
+                                       }
+                                       if ( match < 0 ) {
+                                               /* set search_context_csn to the
+                                                  smallest syncrepl cookie value */
+                                               if ( *search_context_csn ) {
+                                                       ch_free( (*search_context_csn)->bv_val );
+                                                       ch_free( *search_context_csn );
+                                               }
+                                               *search_context_csn = ber_dupbv( NULL,
+                                                                                               syncCookie.ctxcsn );
+                                       }
+                                       slap_sync_cookie_free( &syncCookie, 0 );
+                               } else {
+                                       *search_context_csn = NULL;
+                               } 
+                       } else {
+                               *search_context_csn = NULL;
+                       }
                }
+       } else if ( op->o_sync_mode != SLAP_SYNC_NONE &&
+                LDAP_STAILQ_EMPTY( &op->o_bd->be_syncinfo )) {
+               build_new_dn( &ctxcsn_ndn, &op->o_bd->be_nsuffix[0],
+                                       (struct berval *)&slap_ldapsync_cn_bv, NULL );
 
-ctxcsn_retry :
+provider_ctxcsn_retry :
                rs->sr_err = bdb_dn2entry( op, NULL, &ctxcsn_ndn, &ctxcsn_ei,
                                                                        0, locker, ctxcsn_lock );
                switch(rs->sr_err) {
@@ -286,102 +354,83 @@ ctxcsn_retry :
                                ctxcsn_e = ctxcsn_ei->bei_e;
                        }
                        break;
-        case LDAP_BUSY:
+               case LDAP_BUSY:
                        ch_free( ctxcsn_ndn.bv_val );
                        LOCK_ID_FREE (bdb->bi_dbenv, locker );
                        return LDAP_BUSY;
-        case DB_LOCK_DEADLOCK:
-        case DB_LOCK_NOTGRANTED:
-                       goto ctxcsn_retry;
-        case DB_NOTFOUND:
-                       if ( !op->o_bd->be_syncinfo ) {
-                               snprintf( gid, sizeof( gid ), "%s-%08lx-%08lx",
-                                       bdb_uuid.bv_val, (long) op->o_connid, (long) op->o_opid );
+               case DB_LOCK_DEADLOCK:
+               case DB_LOCK_NOTGRANTED:
+                       goto consumer_ctxcsn_retry;
+               case DB_NOTFOUND:
+                       snprintf( gid, sizeof( gid ), "%s-%08lx-%08lx",
+                               bdb_uuid.bv_val, (long) op->o_connid, (long) op->o_opid );
 
-                               slap_get_csn( op, csnbuf, sizeof(csnbuf), &csn, 1 );
+                       slap_get_csn( op, csnbuf, sizeof(csnbuf), &csn, 1 );
 
-                               if ( 0 ) {
+                       if ( 0 ) {
 txn_retry:
-                                       rs->sr_err = TXN_ABORT( ltid );
-                                       if ( rs->sr_err != 0 ) {
-                                               rs->sr_err = LDAP_OTHER;
-                                               return rs->sr_err;
-                                       }
-                                       ldap_pvt_thread_yield();
-                                       bdb_trans_backoff( ++num_retries );
-                               }
-                               rs->sr_err = TXN_BEGIN( bdb->bi_dbenv, NULL, &ltid, bdb->bi_db_opflags );
+                               rs->sr_err = TXN_ABORT( ltid );
                                if ( rs->sr_err != 0 ) {
                                        rs->sr_err = LDAP_OTHER;
                                        return rs->sr_err;
                                }
+                               ldap_pvt_thread_yield();
+                               bdb_trans_backoff( ++num_retries );
+                       }
+                       rs->sr_err = TXN_BEGIN( bdb->bi_dbenv, NULL,
+                                                               &ltid, bdb->bi_db_opflags );
+                       if ( rs->sr_err != 0 ) {
+                               rs->sr_err = LDAP_OTHER;
+                               return rs->sr_err;
+                       }
 
-                               rs->sr_err = bdb_csn_commit( op, rs, ltid, NULL, &suffix_ei,
-                                                                               &ctxcsn_e, &ctxcsn_added, locker );
-                               switch( rs->sr_err ) {
-                               case BDB_CSN_ABORT:
-                                       LOCK_ID_FREE( bdb->bi_dbenv, locker );
-                                       return LDAP_OTHER;
-                               case BDB_CSN_RETRY:
-                                       goto txn_retry;
-                               }
+                       rs->sr_err = bdb_csn_commit( op, rs, ltid, NULL, &suffix_ei,
+                                                                       &ctxcsn_e, &ctxcsn_added, locker );
+                       switch( rs->sr_err ) {
+                       case BDB_CSN_ABORT:
+                               LOCK_ID_FREE( bdb->bi_dbenv, locker );
+                               return LDAP_OTHER;
+                       case BDB_CSN_RETRY:
+                               goto txn_retry;
+                       }
 
-                               rs->sr_err = TXN_PREPARE( ltid, gid );
-                               if ( rs->sr_err != 0 ) {
-                                       rs->sr_err = LDAP_OTHER;
-                                       return rs->sr_err;
-                               }
+                       rs->sr_err = TXN_PREPARE( ltid, gid );
+                       if ( rs->sr_err != 0 ) {
+                               rs->sr_err = LDAP_OTHER;
+                               return rs->sr_err;
+                       }
 
-                               bdb_cache_add( bdb, suffix_ei, ctxcsn_e,
-                                               (struct berval *)&slap_ldapsync_cn_bv, locker );
+                       bdb_cache_add( bdb, suffix_ei, ctxcsn_e,
+                                       (struct berval *)&slap_ldapsync_cn_bv, locker );
 
-                               rs->sr_err = TXN_COMMIT( ltid, 0 );
-                               if ( rs->sr_err != 0 ) {
-                                       rs->sr_err = LDAP_OTHER;
-                                       return rs->sr_err;
-                               }
+                       rs->sr_err = TXN_COMMIT( ltid, 0 );
+                       if ( rs->sr_err != 0 ) {
+                               rs->sr_err = LDAP_OTHER;
+                               return rs->sr_err;
+                       }
 
-                               ctxcsn_ei = NULL;
-                               rs->sr_err = bdb_dn2entry( op, NULL, &ctxcsn_ndn, &ctxcsn_ei,
-                                                                               0, locker, ctxcsn_lock );
-                               ch_free( ctxcsn_ndn.bv_val );
+                       rs->sr_err = bdb_dn2entry( op, NULL, &ctxcsn_ndn, &ctxcsn_ei,
+                                    0, locker, ctxcsn_lock );
+                       ch_free( ctxcsn_ndn.bv_val );
 
-                               if ( ctxcsn_ei ) {
-                                       ctxcsn_e = ctxcsn_ei->bei_e;
-                               }
-                       } else {
-                               LOCK_ID_FREE( bdb->bi_dbenv, locker );
-                               return LDAP_OTHER;
+                       if ( ctxcsn_ei ) {
+                               ctxcsn_e = ctxcsn_ei->bei_e;
                        }
                        break;
 
                default:
+                       ch_free( ctxcsn_ndn.bv_val );
                        LOCK_ID_FREE (bdb->bi_dbenv, locker );
                        return LDAP_OTHER;
                }
 
                if ( ctxcsn_e ) {
-                       if ( op->o_bd->be_syncinfo ) {
-                               csn_a = attr_find( ctxcsn_e->e_attrs,
-                                       slap_schema.si_ad_syncreplCookie );
-                               if ( csn_a ) {
-                                       struct berval cookie;
-                                       ber_dupbv( &cookie, &csn_a->a_vals[0] );
-                                       ber_bvarray_add( &syncCookie.octet_str, &cookie );
-                                       slap_parse_sync_cookie( &syncCookie );
-                                       *search_context_csn = ber_dupbv( NULL, syncCookie.ctxcsn );
-                                       slap_sync_cookie_free( &syncCookie, 0 );
-                               } else {
-                                       *search_context_csn = NULL;
-                               }
+                       csn_a = attr_find( ctxcsn_e->e_attrs,
+                                               slap_schema.si_ad_contextCSN );
+                       if ( csn_a ) {
+                               *search_context_csn = ber_dupbv( NULL, &csn_a->a_vals[0] );
                        } else {
-                               csn_a = attr_find( ctxcsn_e->e_attrs,
-                                       slap_schema.si_ad_contextCSN );
-                               if ( csn_a ) {
-                                       *search_context_csn = ber_dupbv( NULL, &csn_a->a_vals[0] );
-                               } else {
-                                       *search_context_csn = NULL;
-                               }
+                               *search_context_csn = NULL;
                        }
                } else {
                        *search_context_csn = NULL;
index fa25873ac7b1f5918c3f63b5a858a995edd7f90f..a2633d5c7cf0f0dc1317bd8df4a627ff0046f272 100644 (file)
@@ -251,8 +251,17 @@ retry:     /* transaction retry */
                        matched = NULL;
 
                } else {
-                       BerVarray deref = op->o_bd->be_syncinfo ?
-                               op->o_bd->be_syncinfo->si_provideruri_bv : default_referral;
+                       BerVarray deref = NULL;
+                       if ( !LDAP_STAILQ_EMPTY( &op->o_bd->be_syncinfo )) {
+                               syncinfo_t *si;
+                               LDAP_STAILQ_FOREACH( si, &op->o_bd->be_syncinfo, si_next ) {
+                                       struct berval tmpbv;
+                                       ber_dupbv( &tmpbv, &si->si_provideruri_bv[0] );
+                                       ber_bvarray_add( &deref, &tmpbv );
+                               }
+                       } else {
+                               deref = default_referral;
+                       }
                        rs->sr_ref = referral_rewrite( deref, NULL, &op->o_req_dn,
                                LDAP_SCOPE_DEFAULT );
                }
@@ -260,7 +269,9 @@ retry:      /* transaction retry */
                rs->sr_err = LDAP_REFERRAL;
                send_ldap_result( op, rs );
 
-               ber_bvarray_free( rs->sr_ref );
+               if ( rs->sr_ref != default_referral ) {
+                       ber_bvarray_free( rs->sr_ref );
+               }
                free( (char *)rs->sr_matched );
                rs->sr_ref = NULL;
                rs->sr_matched = NULL;
@@ -472,7 +483,7 @@ retry:      /* transaction retry */
        ldap_pvt_thread_mutex_unlock( &bdb->bi_lastid_mutex );
 #endif
 
-       if ( !op->o_bd->be_syncinfo ) {
+       if ( LDAP_STAILQ_EMPTY( &op->o_bd->be_syncinfo )) {
                rc = bdb_csn_commit( op, rs, ltid, ei, &suffix_ei,
                        &ctxcsn_e, &ctxcsn_added, locker );
                switch ( rc ) {
@@ -494,7 +505,7 @@ retry:      /* transaction retry */
                bdb_cache_delete( &bdb->bi_cache, e, bdb->bi_dbenv,
                        locker, &lock );
 
-               if ( !op->o_bd->be_syncinfo ) {
+               if ( LDAP_STAILQ_EMPTY( &op->o_bd->be_syncinfo )) {
                        if ( ctxcsn_added ) {
                                bdb_cache_add( bdb, suffix_ei,
                                        ctxcsn_e, (struct berval *)&slap_ldapsync_cn_bv, locker );
index ba219deaa57b24151e9f368c37c1045f4eb3051e..31887daa8b686c6eaaff0771148a1087cbe680b3 100644 (file)
@@ -421,8 +421,17 @@ retry:     /* transaction retry */
                        e = NULL;
 
                } else {
-                       BerVarray deref = op->o_bd->be_syncinfo ?
-                               op->o_bd->be_syncinfo->si_provideruri_bv : default_referral;
+                       BerVarray deref = NULL;
+                       if ( !LDAP_STAILQ_EMPTY( &op->o_bd->be_syncinfo )) {
+                               syncinfo_t *si;
+                               LDAP_STAILQ_FOREACH( si, &op->o_bd->be_syncinfo, si_next ) {
+                                       struct berval tmpbv;
+                                       ber_dupbv( &tmpbv, &si->si_provideruri_bv[0] );
+                                       ber_bvarray_add( &deref, &tmpbv );
+                }
+                       } else {
+                               deref = default_referral;
+                       }
                        rs->sr_ref = referral_rewrite( deref, NULL, &op->o_req_dn,
                                LDAP_SCOPE_DEFAULT );
                }
@@ -430,7 +439,9 @@ retry:      /* transaction retry */
                rs->sr_err = LDAP_REFERRAL;
                send_ldap_result( op, rs );
 
-               ber_bvarray_free( rs->sr_ref );
+               if ( rs->sr_ref != default_referral ) {
+                       ber_bvarray_free( rs->sr_ref );
+               }
                free( (char *)rs->sr_matched );
                rs->sr_ref = NULL;
                rs->sr_matched = NULL;
@@ -576,7 +587,7 @@ retry:      /* transaction retry */
                goto return_results;
        }
 
-       if ( !op->o_bd->be_syncinfo ) {
+       if ( LDAP_STAILQ_EMPTY( &op->o_bd->be_syncinfo )) {
                rc = bdb_csn_commit( op, rs, ltid, ei, &suffix_ei,
                        &ctxcsn_e, &ctxcsn_added, locker );
                switch ( rc ) {
@@ -599,7 +610,7 @@ retry:      /* transaction retry */
 
                bdb_cache_modify( e, dummy.e_attrs, bdb->bi_dbenv, locker, &lock );
 
-               if ( !op->o_bd->be_syncinfo ) {
+               if ( LDAP_STAILQ_EMPTY( &op->o_bd->be_syncinfo )) {
                        if ( ctxcsn_added ) {
                                bdb_cache_add( bdb, suffix_ei, ctxcsn_e,
                                        (struct berval *)&slap_ldapsync_cn_bv, locker );
index 18f14807aa7d7e2de4c1dad3a7220e0bbcf07327..ab610aa0b1f4bed39ab6c629dd034f82636ae8e5 100644 (file)
@@ -173,8 +173,17 @@ retry:     /* transaction retry */
                        e = NULL;
 
                } else {
-                       BerVarray deref = op->o_bd->be_syncinfo ?
-                               op->o_bd->be_syncinfo->si_provideruri_bv : default_referral;
+                       BerVarray deref = NULL;
+                       if ( !LDAP_STAILQ_EMPTY( &op->o_bd->be_syncinfo )) {
+                               syncinfo_t *si;
+                               LDAP_STAILQ_FOREACH( si, &op->o_bd->be_syncinfo, si_next ) {
+                                       struct berval tmpbv;
+                                       ber_dupbv( &tmpbv, &si->si_provideruri_bv[0] );
+                                       ber_bvarray_add( &deref, &tmpbv );
+                }
+                       } else {
+                               deref = default_referral;
+                       }
                        rs->sr_ref = referral_rewrite( deref, NULL, &op->o_req_dn,
                                LDAP_SCOPE_DEFAULT );
                }
@@ -940,7 +949,7 @@ retry:      /* transaction retry */
                goto return_results;
        }
 
-       if ( !op->o_bd->be_syncinfo ) {
+       if ( LDAP_STAILQ_EMPTY( &op->o_bd->be_syncinfo )) {
                rc = bdb_csn_commit( op, rs, ltid, ei, &suffix_ei,
                        &ctxcsn_e, &ctxcsn_added, locker );
                switch ( rc ) {
@@ -972,7 +981,7 @@ retry:      /* transaction retry */
                        bdb_cache_modrdn( save, &op->orr_nnewrdn, e, neip,
                                bdb->bi_dbenv, locker, &lock );
 
-                       if ( !op->o_bd->be_syncinfo ) {
+                       if ( LDAP_STAILQ_EMPTY( &op->o_bd->be_syncinfo )) {
                                if ( ctxcsn_added ) {
                                        bdb_cache_add( bdb, suffix_ei, ctxcsn_e,
                                                (struct berval *)&slap_ldapsync_cn_bv, locker );
index f7eed19933acdebc553e1003eb1779c8d626e2ae..6fa23d0ba103ed5836a06bf20eff474d3ba523ab 100644 (file)
@@ -1243,7 +1243,8 @@ id2entry_retry:
                                                        struct berval cookie;
                                                        slap_compose_sync_cookie( sop, &cookie,
                                                                                search_context_csn,
-                                                                               sop->o_sync_state.sid );
+                                                                               sop->o_sync_state.sid,
+                                                                               sop->o_sync_state.rid );
                                                        rs->sr_err = slap_build_sync_state_ctrl( sop,
                                                                rs, e, entry_sync_state, ctrls,
                                                                num_ctrls++, 1, &cookie );
@@ -1388,7 +1389,8 @@ nochange:
                                struct berval cookie;
                                slap_compose_sync_cookie( sop, &cookie,
                                                                                  search_context_csn,
-                                                                                 sop->o_sync_state.sid );
+                                                                                 sop->o_sync_state.sid,
+                                                                                 sop->o_sync_state.rid );
 
                                if ( sync_send_present_mode ) {
                                        rs->sr_err = LDAP_SUCCESS;
@@ -1432,7 +1434,8 @@ nochange:
                                struct berval cookie;
                                slap_compose_sync_cookie( sop, &cookie,
                                                                                  search_context_csn,
-                                                                                 sop->o_sync_state.sid );
+                                                                                 sop->o_sync_state.sid,
+                                                                                 sop->o_sync_state.rid );
 
                                if ( sync_send_present_mode ) {
                                        slap_build_sync_done_ctrl( sop, rs, ctrls,
index ddad52d7a0fb763ca35c8b74e6a903b6eeee9e02..aee408397f1394ff2f5f6e08b1aab0bb72cf90f9 100644 (file)
@@ -60,10 +60,19 @@ ldbm_back_delete(
                        cache_return_entry_r( &li->li_cache, matched );
 
                } else {
-                       BerVarray deref = op->o_bd->be_syncinfo ?
-                               op->o_bd->be_syncinfo->si_provideruri_bv : default_referral;
+                       BerVarray deref = NULL;
+                       if ( !LDAP_STAILQ_EMPTY( &op->o_bd->be_syncinfo )) {
+                               syncinfo_t *si;
+                               LDAP_STAILQ_FOREACH( si, &op->o_bd->be_syncinfo, si_next ) {
+                                       struct berval tmpbv;
+                                       ber_dupbv( &tmpbv, &si->si_provideruri_bv[0] );
+                                       ber_bvarray_add( &deref, &tmpbv );
+                               }
+                       } else {
+                               deref = default_referral;
+                       }
                        rs->sr_ref = referral_rewrite( deref, NULL, &op->o_req_dn,
-                               LDAP_SCOPE_DEFAULT );
+                                                               LDAP_SCOPE_DEFAULT );
                }
 
                ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock);
index bed5eefd8e7e6d2926bff401c86c9ef8a2219092..0823ec072d9d9e0b4b7c76f4063fc4b8940ce050 100644 (file)
@@ -324,10 +324,19 @@ ldbm_back_modify(
                                : NULL;
                        cache_return_entry_r( &li->li_cache, matched );
                } else {
-                       BerVarray deref = op->o_bd->be_syncinfo ?
-                               op->o_bd->be_syncinfo->si_provideruri_bv : default_referral;
+                       BerVarray deref = NULL;
+                       if ( !LDAP_STAILQ_EMPTY( &op->o_bd->be_syncinfo )) {
+                               syncinfo_t *si;
+                               LDAP_STAILQ_FOREACH( si, &op->o_bd->be_syncinfo, si_next ) {
+                                       struct berval tmpbv;
+                                       ber_dupbv( &tmpbv, &si->si_provideruri_bv[0] );
+                                       ber_bvarray_add( &deref, &tmpbv );
+                               }
+                       } else {
+                               deref = default_referral;
+                       }
                        rs->sr_ref = referral_rewrite( deref, NULL, &op->o_req_dn,
-                               LDAP_SCOPE_DEFAULT );
+                                                       LDAP_SCOPE_DEFAULT );
                }
 
                ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock);
index 2c20f1d589f976b0390eabd5bcd40d5965db8eb7..c290fa9af1c8a950cb0d290b0aa8885846d05db6 100644 (file)
@@ -92,10 +92,19 @@ ldbm_back_modrdn(
                                : NULL;
                        cache_return_entry_r( &li->li_cache, matched );
                } else {
-                       BerVarray deref = op->o_bd->be_syncinfo ?
-                               op->o_bd->be_syncinfo->si_provideruri_bv : default_referral;
+                       BerVarray deref = NULL;
+                       if ( !LDAP_STAILQ_EMPTY( &op->o_bd->be_syncinfo )) {
+                               syncinfo_t *si;
+                               LDAP_STAILQ_FOREACH( si, &op->o_bd->be_syncinfo, si_next ) {
+                                       struct berval tmpbv;
+                                       ber_dupbv( &tmpbv, &si->si_provideruri_bv[0] );
+                                       ber_bvarray_add( &deref, &tmpbv );
+                               }
+                       } else {
+                               deref = default_referral;
+                       }
                        rs->sr_ref = referral_rewrite( deref, NULL, &op->o_req_dn,
-                               LDAP_SCOPE_DEFAULT );
+                                                       LDAP_SCOPE_DEFAULT );
                }
 
                ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock);
index 8edb10f2d6ad8cb922fd288b788ef2133bf4cc6f..c9fe4cff150f8b5eb9a2400fe8ce403a01e9faa8 100644 (file)
@@ -337,7 +337,7 @@ int backend_startup(Backend *be)
 #ifndef SLAPD_MULTIMASTER
                if ( backendDB[i].be_update_ndn.bv_val && (
                        !backendDB[i].be_update_refs &&
-                       !backendDB[i].be_syncinfo &&
+                       LDAP_STAILQ_EMPTY( &backendDB[i].be_syncinfo ) &&
                        !default_referral ) )
                {
 #ifdef NEW_LOGGING
@@ -375,14 +375,16 @@ int backend_startup(Backend *be)
                        }
                }
 
-               if ( backendDB[i].be_syncinfo != NULL ) {
-                       syncinfo_t *si = ( syncinfo_t * ) backendDB[i].be_syncinfo;
-                       si->si_be = &backendDB[i];
-                       init_syncrepl(si);
-                       ldap_pvt_thread_mutex_lock( &syncrepl_rq.rq_mutex );
-                       ldap_pvt_runqueue_insert( &syncrepl_rq, si->si_interval,
-                               do_syncrepl, (void *) backendDB[i].be_syncinfo );
-                       ldap_pvt_thread_mutex_unlock( &syncrepl_rq.rq_mutex );
+               if ( !LDAP_STAILQ_EMPTY( &backendDB[i].be_syncinfo )) {
+                       syncinfo_t *si;
+                       LDAP_STAILQ_FOREACH( si, &backendDB[i].be_syncinfo, si_next ) {
+                               si->si_be = &backendDB[i];
+                               init_syncrepl( si );
+                               ldap_pvt_thread_mutex_lock( &syncrepl_rq.rq_mutex );
+                               ldap_pvt_runqueue_insert( &syncrepl_rq,
+                                               si->si_interval, do_syncrepl, (void *) si );
+                               ldap_pvt_thread_mutex_unlock( &syncrepl_rq.rq_mutex );
+                       }
                }
        }
 
@@ -552,7 +554,7 @@ backend_db_init(
        ldap_pvt_thread_mutex_init( &be->be_pcl_mutex );
        ldap_pvt_thread_mutex_init( &be->be_context_csn_mutex );
 
-       be->be_syncinfo = NULL;
+       LDAP_STAILQ_INIT( &be->be_syncinfo );
 
        /* assign a default depth limit for alias deref */
        be->be_max_deref_depth = SLAPD_DEFAULT_MAXDEREFDEPTH; 
index 881e42882319d24f443291bf7878aee52e224847..da9e1474268e6a99093945cbc2ef4f4a8c7d8687 100644 (file)
@@ -2755,21 +2755,11 @@ add_syncrepl(
 )
 {
        syncinfo_t *si;
+       syncinfo_t *si_entry;
+       int     rc = 0;
+       int duplicated_replica_id = 0;
 
-       if ( be->be_syncinfo ) {
-#ifdef NEW_LOGGING
-               LDAP_LOG( CONFIG, INFO, 
-                           "add_syncrepl: multiple syncrepl lines in a database "
-                               "definition are yet to be supported.\n", 0, 0, 0 );
-#else
-               Debug( LDAP_DEBUG_ANY,
-                           "add_syncrepl: multiple syncrepl lines in a database "
-                               "definition are yet to be supported.\n", 0, 0, 0 );
-#endif
-               return 1;
-       }
-
-       si = be->be_syncinfo = (syncinfo_t *) ch_calloc( 1, sizeof( syncinfo_t ) );
+       si = (syncinfo_t *) ch_calloc( 1, sizeof( syncinfo_t ) );
 
        if ( si == NULL ) {
 #ifdef NEW_LOGGING
@@ -2807,15 +2797,55 @@ add_syncrepl(
        si->si_presentlist = NULL;
        LDAP_LIST_INIT( &si->si_nonpresentlist );
 
-       if ( parse_syncrepl_line( cargv, cargc, si ) < 0 ) {
+       rc = parse_syncrepl_line( cargv, cargc, si );
+
+       LDAP_STAILQ_FOREACH( si_entry, &be->be_syncinfo, si_next ) {
+               if ( si->si_id == si_entry->si_id ) {
+#ifdef NEW_LOGGING
+                       LDAP_LOG( CONFIG, ERR,
+                                       "add_syncrepl: duplicaetd replica id\n", 0, 0,0 );
+#else
+                       Debug( LDAP_DEBUG_ANY,
+                                       "add_syncrepl: duplicated replica id\n",0, 0, 0 );
+#endif
+                       duplicated_replica_id = 1;
+                       break;
+               }
+       }
+
+       if ( rc < 0 || duplicated_replica_id ) {
+               syncinfo_t *si_entry;
                /* Something bad happened - back out */
 #ifdef NEW_LOGGING
                LDAP_LOG( CONFIG, ERR, "failed to add syncinfo\n", 0, 0,0 );
 #else
                Debug( LDAP_DEBUG_ANY, "failed to add syncinfo\n", 0, 0, 0 );
 #endif
-               free( si );
-               be->be_syncinfo = NULL;
+
+               /* If error, remove all syncinfo */
+               LDAP_STAILQ_FOREACH( si_entry, &be->be_syncinfo, si_next ) {
+                       if ( si_entry->si_updatedn.bv_val ) {
+                               ch_free( si->si_updatedn.bv_val );
+                       }
+                       if ( si_entry->si_filterstr.bv_val ) {
+                               ch_free( si->si_filterstr.bv_val );
+                       }
+                       if ( si_entry->si_attrs ) {
+                               int i;
+                               while ( si_entry->si_attrs[i] != NULL ) {
+                                       ch_free( si_entry->si_attrs[i] );
+                                       i++;
+                               }
+                               ch_free( si_entry->si_attrs );
+                       }
+               }
+
+               while ( !LDAP_STAILQ_EMPTY( &be->be_syncinfo )) {
+                       si_entry = LDAP_STAILQ_FIRST( &be->be_syncinfo );
+                       LDAP_STAILQ_REMOVE_HEAD( &be->be_syncinfo, si_next );
+                       ch_free( si_entry );
+               }
+               LDAP_STAILQ_INIT( &be->be_syncinfo );
                return 1;
        } else {
 #ifdef NEW_LOGGING
@@ -2831,6 +2861,7 @@ add_syncrepl(
                        be->be_flags |= SLAP_BFLAG_NO_SCHEMA_CHECK;
                }
                si->si_be = be;
+               LDAP_STAILQ_INSERT_TAIL( &be->be_syncinfo, si, si_next );
                return 0;
        }
 }
index cebb526c043216e7c5210c12418132cfc574b91e..45a3d9d2e376bcbb36d9ec6f15c6043b93914d3e 100644 (file)
@@ -192,10 +192,10 @@ do_delete(
                /* do the update here */
                int repl_user = be_isupdate( op->o_bd, &op->o_ndn );
 #ifndef SLAPD_MULTIMASTER
-               if ( !op->o_bd->be_syncinfo &&
+               if ( LDAP_STAILQ_EMPTY( &op->o_bd->be_syncinfo ) &&
                        ( !op->o_bd->be_update_ndn.bv_len || repl_user ))
 #else
-               if ( !op->o_bd->be_syncinfo )
+               if ( LDAP_STAILQ_EMPTY( &op->o_bd->be_syncinfo ))
 #endif
                {
 
@@ -216,8 +216,13 @@ do_delete(
 #ifndef SLAPD_MULTIMASTER
                } else {
                        BerVarray defref = NULL;
-                       if ( op->o_bd->be_syncinfo ) {
-                               defref = op->o_bd->be_syncinfo->si_provideruri_bv;
+                       if ( !LDAP_STAILQ_EMPTY( &op->o_bd->be_syncinfo )) {
+                               syncinfo_t *si;
+                               LDAP_STAILQ_FOREACH( si, &op->o_bd->be_syncinfo, si_next ) {
+                                       struct berval tmpbv;
+                                       ber_dupbv( &tmpbv, &si->si_provideruri_bv[0] );
+                                       ber_bvarray_add( &defref, &tmpbv );
+                               }
                        } else {
                                defref = op->o_bd->be_update_refs
                                        ? op->o_bd->be_update_refs : default_referral;
index 1869805805b6daf01aeb11bc761d7ac5ab547f66..ae1773f592dfb3da419fcc066227e4371172cb3f 100644 (file)
@@ -26,4 +26,6 @@ const struct berval slap_unknown_bv = BER_BVC("unknown");
 const struct berval slap_true_bv = BER_BVC("TRUE");
 const struct berval slap_false_bv = BER_BVC("FALSE");
 
-struct sync_cookie *slap_sync_cookie = NULL;
+//struct sync_cookie *slap_sync_cookie = NULL;
+struct slap_sync_cookie_s slap_sync_cookie =
+                       LDAP_STAILQ_HEAD_INITIALIZER( slap_sync_cookie );
index 7d62ef860f4a2ddac79940d1727ce2bb7ffc7d87..bb2af08c80eea6f9fb319004416e9a44cc16e981 100644 (file)
@@ -306,23 +306,46 @@ slap_compose_sync_cookie(
        Operation *op,
        struct berval *cookie,
        struct berval *csn,
-       int sid )
+       int sid,
+       int rid )
 {
-       char cookiestr[ LDAP_LUTIL_CSNSTR_BUFSIZE + 10 ];
+       char cookiestr[ LDAP_LUTIL_CSNSTR_BUFSIZE + 20 ];
 
        if ( csn->bv_val == NULL ) {
                if ( sid == -1 ) {
-                       cookiestr[0] = '\0';
+                       if ( rid == -1 ) {
+                               cookiestr[0] = '\0';
+                       } else {
+                               snprintf( cookiestr, LDAP_LUTIL_CSNSTR_BUFSIZE + 20,
+                                               "rid=%03d", rid );
+                       }
                } else {
-                       snprintf( cookiestr, LDAP_LUTIL_CSNSTR_BUFSIZE + 10,
+                       if ( rid == -1 ) {
+                               snprintf( cookiestr, LDAP_LUTIL_CSNSTR_BUFSIZE + 20,
                                                "sid=%03d", sid );
+                       } else {
+                               snprintf( cookiestr, LDAP_LUTIL_CSNSTR_BUFSIZE + 20,
+                                               "sid=%03d,rid=%03d", sid, rid );
+                       }
                }
-       } else if ( sid == -1 ) {
-               snprintf( cookiestr, LDAP_LUTIL_CSNSTR_BUFSIZE + 10,
-                                               "csn=%s", csn->bv_val );
        } else {
-               snprintf( cookiestr, LDAP_LUTIL_CSNSTR_BUFSIZE + 10,
+               if ( sid == -1 ) {
+                       if ( rid == -1 ) {
+                               snprintf( cookiestr, LDAP_LUTIL_CSNSTR_BUFSIZE + 20,
+                                               "csn=%s", csn->bv_val );
+                       } else {
+                               snprintf( cookiestr, LDAP_LUTIL_CSNSTR_BUFSIZE + 20,
+                                               "csn=%s,rid=%03d", csn->bv_val, rid );
+                       }
+               } else {
+                       if ( rid == -1 ) {
+                               snprintf( cookiestr, LDAP_LUTIL_CSNSTR_BUFSIZE + 20,
                                                "csn=%s,sid=%03d", csn->bv_val, sid );
+                       } else {
+                               snprintf( cookiestr, LDAP_LUTIL_CSNSTR_BUFSIZE + 20,
+                                               "csn=%s,sid=%03d,rid=%03d", csn->bv_val, sid, rid );
+                       }
+               }
        }
        ber_str2bv( cookiestr, strlen(cookiestr), 1, cookie );
 }
@@ -363,6 +386,8 @@ slap_parse_sync_cookie(
        int csn_str_len;
        char *sid_ptr;
        char *sid_str;
+       char *rid_ptr;
+       char *rid_str;
        char *cval;
        struct berval *ctxcsn;
 
@@ -399,6 +424,18 @@ slap_parse_sync_cookie(
        } else {
                cookie->sid = -1;
        }
+
+       if (( rid_ptr = strstr( cookie->octet_str->bv_val, "rid=" )) != NULL ) {
+               rid_str = (char *) SLAP_STRNDUP( rid_ptr,
+                                                       SLAP_SYNC_RID_SIZE + sizeof("rid=") - 1 );
+               if ( cval = strchr( rid_str, ',' )) {
+                       *cval = '\0';
+               }
+               cookie->rid = atoi( rid_str + sizeof("rid=") - 1 );
+               ch_free( rid_str );
+       } else {
+               cookie->rid = -1;
+       }
 }
 
 int
@@ -457,6 +494,7 @@ slap_dup_sync_cookie(
        }
 
        new->sid = src->sid;
+       new->rid = src->rid;
 
        if ( src->ctxcsn ) {
                for ( i=0; src->ctxcsn[i].bv_val; i++ ) {
index c15dee8c1dae1c8ae0bf296ba77a8cb26dadc2f8..cf64811cb64ca20b4d0a2f04566f36f72cad6836 100644 (file)
@@ -146,6 +146,8 @@ int main( int argc, char **argv )
        int         serverMode = SLAP_SERVER_MODE;
 
        struct berval cookie = { 0, NULL };
+       struct sync_cookie *scp = NULL;
+       struct sync_cookie *scp_entry = NULL;
 
 #ifdef CSRIMALLOC
        FILE *leakfile;
@@ -244,16 +246,31 @@ int main( int argc, char **argv )
                case 'h':       /* listen URLs */
                        if ( urls != NULL ) free( urls );
                        urls = ch_strdup( optarg );
-           break;
+                       break;
 
                case 'c':       /* provide sync cookie, override if exist in replica */
-                       if ( slap_sync_cookie ) {
-                               slap_sync_cookie_free( slap_sync_cookie, 1 );
-                       }
-                       slap_sync_cookie = (struct sync_cookie *) ch_calloc( 1,
-                                                               sizeof( struct sync_cookie ));
+                       scp = (struct sync_cookie *) ch_calloc( 1,
+                                                                               sizeof( struct sync_cookie ));
                        ber_str2bv( optarg, strlen( optarg ), 1, &cookie );
-                       ber_bvarray_add( &slap_sync_cookie->octet_str, &cookie );
+                       ber_bvarray_add( &scp->octet_str, &cookie );
+                       slap_parse_sync_cookie( scp );
+
+                       LDAP_STAILQ_FOREACH( scp_entry, &slap_sync_cookie, sc_next ) {
+                               if ( scp->rid == scp_entry->rid ) {
+#ifdef NEW_LOGGING
+                                       LDAP_LOG( OPERATION, CRIT,
+                                                       "main: duplicated replica id in cookies\n",
+                                                       0, 0, 0 );
+#else
+                                       Debug( LDAP_DEBUG_ANY,
+                                                   "main: duplicated replica id in cookies\n",
+                                                       0, 0, 0 );
+#endif
+                                       slap_sync_cookie_free( scp, 1 );
+                                       goto destroy;
+                               }
+                       }
+                       LDAP_STAILQ_INSERT_TAIL( &slap_sync_cookie, scp, sc_next );
                        break;
 
                case 'd':       /* set debug level and 'do not detach' flag */
@@ -605,6 +622,12 @@ destroy:
        /* remember an error during destroy */
        rc |= slap_destroy();
 
+       while ( !LDAP_STAILQ_EMPTY( &slap_sync_cookie )) {
+               scp = LDAP_STAILQ_FIRST( &slap_sync_cookie );
+               LDAP_STAILQ_REMOVE_HEAD( &slap_sync_cookie, sc_next );
+               ch_free( scp );
+       }
+
 #ifdef SLAPD_MODULES
        module_kill();
 #endif
index eebb174c0dfa1aeb648b8f4a1060a1c3ac26fbb8..4c28b687b2fb53b3b7e318d339d8138e4999ab18 100644 (file)
@@ -455,10 +455,10 @@ do_modify(
                 * because it accepts each modify request
                 */
 #ifndef SLAPD_MULTIMASTER
-               if ( !op->o_bd->be_syncinfo &&
+               if ( LDAP_STAILQ_EMPTY( &op->o_bd->be_syncinfo ) &&
                        ( !op->o_bd->be_update_ndn.bv_len || repl_user ))
 #else
-               if ( !op->o_bd->be_syncinfo )
+               if ( LDAP_STAILQ_EMPTY( &op->o_bd->be_syncinfo ))
 #endif
                {
                        int update = op->o_bd->be_update_ndn.bv_len;
@@ -503,8 +503,13 @@ do_modify(
                /* send a referral */
                } else {
                        BerVarray defref = NULL;
-                       if ( op->o_bd->be_syncinfo ) {
-                               defref = op->o_bd->be_syncinfo->si_provideruri_bv;
+                       if ( !LDAP_STAILQ_EMPTY( &op->o_bd->be_syncinfo )) {
+                               syncinfo_t *si;
+                               LDAP_STAILQ_FOREACH( si, &op->o_bd->be_syncinfo, si_next ) {
+                                       struct berval tmpbv;
+                                       ber_dupbv( &tmpbv, &si->si_provideruri_bv[0] );
+                                       ber_bvarray_add( &defref, &tmpbv );
+                               }
                        } else {
                                defref = op->o_bd->be_update_refs
                                                ? op->o_bd->be_update_refs : default_referral;
index f63aca9d5637d40e15694d493ac3a6c3991f7034..fdd360f8bd1b6e1e8727481c0ec7d21c7e78f646 100644 (file)
@@ -353,10 +353,10 @@ do_modrdn(
                /* do the update here */
                int repl_user = be_isupdate( op->o_bd, &op->o_ndn );
 #ifndef SLAPD_MULTIMASTER
-               if ( !op->o_bd->be_syncinfo &&
+               if ( LDAP_STAILQ_EMPTY( &op->o_bd->be_syncinfo ) &&
                        ( !op->o_bd->be_update_ndn.bv_len || repl_user ))
 #else
-               if ( !op->o_bd->be_syncinfo )
+               if ( LDAP_STAILQ_EMPTY( &op->o_bd->be_syncinfo ))
 #endif
                {
                        op->orr_deleteoldrdn = deloldrdn;
@@ -370,8 +370,13 @@ do_modrdn(
 #ifndef SLAPD_MULTIMASTER
                } else {
                        BerVarray defref = NULL;
-                       if ( op->o_bd->be_syncinfo ) {
-                               defref = op->o_bd->be_syncinfo->si_provideruri_bv;
+                       if ( !LDAP_STAILQ_EMPTY( &op->o_bd->be_syncinfo )) {
+                               syncinfo_t *si;
+                               LDAP_STAILQ_FOREACH( si, &op->o_bd->be_syncinfo, si_next ) {
+                                       struct berval tmpbv;
+                                       ber_dupbv( &tmpbv, &si->si_provideruri_bv[0] );
+                                       ber_bvarray_add( &defref, &tmpbv );
+                               }
                        } else {
                                defref = op->o_bd->be_update_refs
                                        ? op->o_bd->be_update_refs : default_referral;
index cfd3253f7fd4edbfdfff40974dba8c0c377e73f9..228b631df7cf5675a66d5c8726c1d401d4c0c529 100644 (file)
@@ -57,8 +57,13 @@ int passwd_extop(
        } else if( op->o_bd->be_update_ndn.bv_len ) {
                /* we SHOULD return a referral in this case */
                BerVarray defref = NULL;
-               if ( op->o_bd->be_syncinfo ) {
-                       defref = op->o_bd->be_syncinfo->si_provideruri_bv;
+               if ( !LDAP_STAILQ_EMPTY( &op->o_bd->be_syncinfo )) {
+                       syncinfo_t *si;
+                       LDAP_STAILQ_FOREACH( si, &op->o_bd->be_syncinfo, si_next ) {
+                               struct berval tmpbv;
+                               ber_dupbv( &tmpbv, &si->si_provideruri_bv[0] );
+                               ber_bvarray_add( &defref, &tmpbv );
+                       }
                } else {
                        defref = referral_rewrite( op->o_bd->be_update_refs,
                                NULL, NULL, LDAP_SCOPE_DEFAULT );
index f65144c3e263353c5961b099f881a58d869056d0..fa7de1b93338171d132eb2ac2511d73a0f08a3ad 100644 (file)
@@ -551,7 +551,7 @@ LDAP_SLAPD_V( const struct berval ) slap_empty_bv;
 LDAP_SLAPD_V( const struct berval ) slap_unknown_bv;
 LDAP_SLAPD_V( const struct berval ) slap_true_bv;
 LDAP_SLAPD_V( const struct berval ) slap_false_bv;
-LDAP_SLAPD_V( struct sync_cookie * ) slap_sync_cookie;
+LDAP_SLAPD_V( struct slap_sync_cookie_s ) slap_sync_cookie;
 
 /*
  * index.c
@@ -592,7 +592,7 @@ LDAP_SLAPD_F (int) slap_send_syncinfo LDAP_P((
                                Operation *, SlapReply *, int,
                                struct berval *, int, BerVarray, int ));
 LDAP_SLAPD_F (void) slap_compose_sync_cookie LDAP_P((
-                               Operation *, struct berval *, struct berval *, int ));
+                               Operation *, struct berval *, struct berval *, int, int ));
 LDAP_SLAPD_F (void) slap_sync_cookie_free LDAP_P((
                                struct sync_cookie *, int free_cookie ));
 LDAP_SLAPD_F (int) slap_parse_sync_cookie LDAP_P((
index 4185bba5fc4803a8fa753503224b067e896819f1..e0bcbc5fedc137d3d3e35ae093a680973bde7207 100644 (file)
@@ -1292,6 +1292,7 @@ typedef BackendDB Backend;
  */
 
 #define SLAP_SYNC_SID_SIZE     3
+#define SLAP_SYNC_RID_SIZE     3
 #define SLAP_SYNCUUID_SET_SIZE 256
 
 struct nonpresent_entry {
@@ -1304,11 +1305,15 @@ struct sync_cookie {
        struct berval *ctxcsn;
        long sid;
        struct berval *octet_str;
+       long rid;
+       LDAP_STAILQ_ENTRY(sync_cookie) sc_next;
 };
 
+LDAP_STAILQ_HEAD( slap_sync_cookie_s, sync_cookie );
+
 typedef struct syncinfo_s {
         struct slap_backend_db *si_be;
-        unsigned int           si_id;
+        long                           si_id;
         char                           *si_provideruri;
         BerVarray                      si_provideruri_bv;
 #define SYNCINFO_TLS_OFF               0
@@ -1341,6 +1346,7 @@ typedef struct syncinfo_s {
         Avlnode                                *si_presentlist;
                LDAP                            *si_ld;
                LDAP_LIST_HEAD(np, nonpresent_entry) si_nonpresentlist;
+               LDAP_STAILQ_ENTRY( syncinfo_s ) si_next;
 } syncinfo_t;
 
 struct slap_backend_db {
@@ -1495,7 +1501,7 @@ struct slap_backend_db {
        ldap_pvt_thread_mutex_t                                 be_pcl_mutex;
        struct berval                                                   be_context_csn;
        ldap_pvt_thread_mutex_t                                 be_context_csn_mutex;
-       syncinfo_t      *be_syncinfo;   /* For syncrepl */
+       LDAP_STAILQ_HEAD( be_si, syncinfo_s )   be_syncinfo; /* For syncrepl */
 };
 
 struct slap_conn;
index ef28f922cd2f4de33c4f510c8a8325f2f84a4cb9..12cb666b32859ca326dea054dc79b37ca0e1c810 100644 (file)
@@ -187,9 +187,11 @@ do_syncrep1(
        syncinfo_t *si )
 {
        int     rc;
+       int cmdline_cookie_found = 0;
 
        char syncrepl_cbuf[sizeof(CN_STR SYNCREPL_STR)];
        struct berval syncrepl_cn_bv;
+       struct sync_cookie      *sc = NULL;
        struct sync_cookie      syncCookie = { NULL, -1, NULL };
 
        /* Init connection to master */
@@ -313,14 +315,20 @@ do_syncrep1(
                op->o_tmpmemctx );
        op->o_req_dn = op->o_req_ndn;
 
-       if ( slap_sync_cookie != NULL ) {
-               /* cookie is supplied in the command line */
+       LDAP_STAILQ_FOREACH( sc, &slap_sync_cookie, sc_next ) {
+               if ( si->si_id == sc->rid ) {
+                       cmdline_cookie_found = 1;
+                       break;
+               }
+       }
 
+       if ( cmdline_cookie_found ) {
+               /* cookie is supplied in the command line */
                BerVarray cookie = NULL;
                struct berval cookie_bv;
 
+               LDAP_STAILQ_REMOVE( &slap_sync_cookie, sc, sync_cookie, sc_next );
                slap_sync_cookie_free( &si->si_syncCookie, 0 );
-               slap_parse_sync_cookie( slap_sync_cookie );
 
                /* read stored cookie if it exists */
                backend_attribute( op, NULL, &op->o_req_ndn,
@@ -328,36 +336,40 @@ do_syncrep1(
 
                if ( !cookie ) {
                        /* no stored cookie */
-                       if ( slap_sync_cookie->ctxcsn == NULL ||
-                                slap_sync_cookie->ctxcsn->bv_val == NULL ) {
-                               /* if slap_sync_cookie does not have ctxcsn component */
-                               /* set it to an initial value */
-                               slap_init_sync_cookie_ctxcsn( slap_sync_cookie );
+                       if ( sc->ctxcsn == NULL ||
+                                sc->ctxcsn->bv_val == NULL ) {
+                               /* if cmdline cookie does not have ctxcsn */
+                               /* component, set it to an initial value */
+                               slap_init_sync_cookie_ctxcsn( sc );
                        }
-                       slap_dup_sync_cookie( &si->si_syncCookie, slap_sync_cookie );
-                       slap_sync_cookie_free( slap_sync_cookie, 1 );
-                       slap_sync_cookie = NULL;
+                       slap_dup_sync_cookie( &si->si_syncCookie, sc );
+                       slap_sync_cookie_free( sc, 1 );
+                       sc = NULL;
                } else {
                        /* stored cookie */
                        ber_dupbv( &cookie_bv, &cookie[0] );
                        ber_bvarray_add( &si->si_syncCookie.octet_str, &cookie_bv );
                        slap_parse_sync_cookie( &si->si_syncCookie );
                        ber_bvarray_free_x( cookie, op->o_tmpmemctx );
-                       if ( slap_sync_cookie->sid != -1 ) {
+                       if ( sc->sid != -1 ) {
                                /* command line cookie wins */
-                               si->si_syncCookie.sid = slap_sync_cookie->sid;
+                               si->si_syncCookie.sid = sc->sid;
                        }
-                       if ( slap_sync_cookie->ctxcsn != NULL ) {
+                       if ( sc->ctxcsn != NULL ) {
                                /* command line cookie wins */
                                if ( si->si_syncCookie.ctxcsn ) {
                                        ber_bvarray_free( si->si_syncCookie.ctxcsn );
                                        si->si_syncCookie.ctxcsn = NULL;
                                }
-                               ber_dupbv( &cookie_bv, &slap_sync_cookie->ctxcsn[0] );
+                               ber_dupbv( &cookie_bv, &sc->ctxcsn[0] );
                                ber_bvarray_add( &si->si_syncCookie.ctxcsn, &cookie_bv );
                        }
-                       slap_sync_cookie_free( slap_sync_cookie, 1 );
-                       slap_sync_cookie = NULL;
+                       if ( sc->rid != -1 ) {
+                               /* command line cookie wins */
+                               si->si_syncCookie.rid = sc->rid;
+                       }
+                       slap_sync_cookie_free( sc, 1 );
+                       sc = NULL;
                }
        } else {
                /* no command line cookie is specified */