]> git.sur5r.net Git - openldap/commitdiff
Optimization: send sid in cookie to avoid getting our changes sent
authorHoward Chu <hyc@openldap.org>
Mon, 5 Feb 2007 23:10:22 +0000 (23:10 +0000)
committerHoward Chu <hyc@openldap.org>
Mon, 5 Feb 2007 23:10:22 +0000 (23:10 +0000)
back to us.

servers/slapd/ldapsync.c
servers/slapd/overlays/syncprov.c
servers/slapd/proto-slap.h
servers/slapd/slap.h
servers/slapd/syncrepl.c

index 59334851d7787438f3623be7fca70f6c02082fa6..143b10233fc68725ad1c6f78fd6c538c57b1864d 100644 (file)
@@ -35,7 +35,8 @@ slap_compose_sync_cookie(
        Operation *op,
        struct berval *cookie,
        BerVarray csn,
-       int rid )
+       int rid,
+       int sid )
 {
        int len, numcsn = 0;
 
@@ -51,6 +52,9 @@ slap_compose_sync_cookie(
                } else {
                        len = snprintf( cookiestr, sizeof( cookiestr ),
                                        "rid=%03d", rid );
+                       if ( sid >= 0 ) {
+                               len += sprintf( cookiestr+len, ",sid=%03x", sid );
+                       }
                }
                ber_str2bv_x( cookiestr, len, 1, cookie, 
                        op ? op->o_tmpmemctx : NULL );
@@ -63,10 +67,17 @@ slap_compose_sync_cookie(
                        len += csn[i].bv_len + 1;
 
                len += STRLENOF("rid=123,csn=");
+               if ( sid >= 0 )
+                       len += STRLENOF("sid=xxx,");
+
                cookie->bv_val = slap_sl_malloc( len, op ? op->o_tmpmemctx : NULL );
 
-               len = sprintf( cookie->bv_val, "rid=%03d,csn=", rid );
+               len = sprintf( cookie->bv_val, "rid=%03d,", rid );
                ptr = cookie->bv_val + len;
+               if ( sid >= 0 ) {
+                       ptr += sprintf( ptr, "sid=%03x,", sid );
+               }
+               ptr = lutil_strcopy( ptr, "csn=" );
                for ( i=0; i<numcsn; i++) {
                        ptr = lutil_strncopy( ptr, csn[i].bv_val, csn[i].bv_len );
                        *ptr++ = ';';
@@ -160,6 +171,7 @@ slap_parse_sync_cookie(
                return -1;
 
        cookie->rid = -1;
+       cookie->sid = -1;
        cookie->ctxcsn = NULL;
        cookie->sids = NULL;
        cookie->numcsns = 0;
@@ -181,6 +193,17 @@ slap_parse_sync_cookie(
                        }
                        continue;
                }
+               if ( !strncmp( next, "sid=", STRLENOF("sid=") )) {
+                       rid_ptr = next;
+                       cookie->sid = strtoul( &rid_ptr[ STRLENOF( "sid=" ) ], &next, 16 );
+                       if ( next == rid_ptr || next > end || *next != ',' ) {
+                               return -1;
+                       }
+                       if ( *next == ',' ) {
+                               next++;
+                       }
+                       continue;
+               }
                if ( !strncmp( next, "csn=", STRLENOF("csn=") )) {
                        slap_syntax_validate_func *validate;
                        struct berval stamp;
@@ -258,6 +281,7 @@ slap_init_sync_cookie_ctxcsn(
        cookie->ctxcsn = NULL;
        value_add_one( &cookie->ctxcsn, &ctxcsn );
        cookie->numcsns = 1;
+       cookie->sid = slap_serverID;
 
        return 0;
 }
@@ -287,6 +311,7 @@ slap_dup_sync_cookie(
        }
 
        new->rid = src->rid;
+       new->sid = src->sid;
        new->numcsns = src->numcsns;
 
        if ( src->numcsns ) {
index b6b7eb45b3904e6f7c8c4b45423f2420fcf2ea36..8a824513c1612f79711bd2c91fc401cb83787d16 100644 (file)
@@ -59,6 +59,7 @@ typedef struct syncops {
        ID              s_eid;          /* entryID of search base */
        Operation       *s_op;          /* search op */
        int             s_rid;
+       int             s_sid;
        struct berval s_filterstr;
        int             s_flags;        /* search status */
 #define        PS_IS_REFRESHING        0x01
@@ -769,7 +770,7 @@ syncprov_sendresp( Operation *op, opcookie *opc, syncops *so,
        ctrls[1] = NULL;
        csns[0] = opc->sctxcsn;
        BER_BVZERO( &csns[1] );
-       slap_compose_sync_cookie( op, &cookie, csns, so->s_rid );
+       slap_compose_sync_cookie( op, &cookie, csns, so->s_rid, so->s_sid );
 
        e_uuid.e_attrs = &a_uuid;
        a_uuid.a_desc = slap_schema.si_ad_entryUUID;
@@ -977,6 +978,12 @@ static int
 syncprov_qresp( opcookie *opc, syncops *so, int mode )
 {
        syncres *sr;
+       int sid;
+
+       /* Don't send changes back to their originator */
+       sid = slap_parse_csn_sid( &opc->sctxcsn );
+       if ( sid == so->s_sid )
+               return LDAP_SUCCESS;
 
        sr = ch_malloc(sizeof(syncres) + opc->suuid.bv_len + 1 +
                opc->sdn.bv_len + 1 + opc->sndn.bv_len + 1 + opc->sctxcsn.bv_len + 1 );
@@ -1523,7 +1530,8 @@ syncprov_playlog( Operation *op, SlapReply *rs, sessionlog *sl,
        if ( ndel ) {
                struct berval cookie;
 
-               slap_compose_sync_cookie( op, &cookie, delcsn, srs->sr_state.rid );
+               slap_compose_sync_cookie( op, &cookie, delcsn, srs->sr_state.rid,
+                       srs->sr_state.sid );
                uuids[ndel].bv_val = NULL;
                syncprov_sendinfo( op, rs, LDAP_TAG_SYNC_ID_SET, &cookie, 0, uuids, 1 );
                op->o_tmpfree( cookie.bv_val, op->o_tmpmemctx );
@@ -1919,6 +1927,13 @@ syncprov_search_response( Operation *op, SlapReply *rs )
                        int i, sid;
                        sid = slap_parse_csn_sid( &a->a_nvals[0] );
 
+                       /* Don't send changed entries back to the originator */
+                       if ( sid == srs->sr_state.sid ) {
+                               Debug( LDAP_DEBUG_SYNC,
+                                       "Entry %s changed by peer, ignored\n",
+                                       rs->sr_entry->e_name.bv_val, 0, 0 );
+                               return LDAP_SUCCESS;
+                       }
                        /* Make sure entry is less than the snapshot'd contextCSN */
                        for ( i=0; i<ss->ss_numcsns; i++ ) {
                                if ( sid == ss->ss_sids[i] && ber_bvcmp( &a->a_nvals[0],
@@ -1957,7 +1972,7 @@ syncprov_search_response( Operation *op, SlapReply *rs )
                struct berval cookie;
 
                slap_compose_sync_cookie( op, &cookie, ss->ss_ctxcsn,
-                       srs->sr_state.rid );
+                       srs->sr_state.rid, srs->sr_state.sid );
 
                /* Is this a regular refresh? */
                if ( !ss->ss_so ) {
@@ -2051,6 +2066,7 @@ syncprov_op_search( Operation *op, SlapReply *rs )
                *sop = so;
                ldap_pvt_thread_mutex_init( &sop->s_mutex );
                sop->s_rid = srs->sr_state.rid;
+               sop->s_rid = srs->sr_state.sid;
                sop->s_inuse = 1;
 
                ldap_pvt_thread_mutex_lock( &si->si_ops_mutex );
index d04794faf395b8e0c04556c55d150817b87c5859..29d87999718cba4ee4e87ce11b14954e389b01c2 100644 (file)
@@ -1016,7 +1016,7 @@ LDAP_SLAPD_V (char *)     slap_known_controls[];
  * ldapsync.c
  */
 LDAP_SLAPD_F (void) slap_compose_sync_cookie LDAP_P((
-                               Operation *, struct berval *, BerVarray, int ));
+                               Operation *, struct berval *, BerVarray, int, int ));
 LDAP_SLAPD_F (void) slap_sync_cookie_free LDAP_P((
                                struct sync_cookie *, int free_cookie ));
 LDAP_SLAPD_F (int) slap_parse_csn_sid LDAP_P((
index 0495eb00479be7cf514c23088c6acc13911ad276..f4c1cf7d1d99f32796b03ab0d7f4f0149a257d24 100644 (file)
@@ -1661,6 +1661,7 @@ struct sync_cookie {
        struct berval *ctxcsn;
        struct berval octet_str;
        int rid;
+       int sid;
        int numcsns;
        int *sids;
        LDAP_STAILQ_ENTRY(sync_cookie) sc_next;
index 154734e68f727e2863ce8c4f77f6ed332b76229e..7e72db64f41b8353a90590d1192bff60f60ba688 100644 (file)
@@ -520,13 +520,14 @@ do_syncrep1(
                }
 
                slap_compose_sync_cookie( NULL, &si->si_syncCookie.octet_str,
-                       si->si_syncCookie.ctxcsn, si->si_syncCookie.rid );
+                       si->si_syncCookie.ctxcsn, si->si_syncCookie.rid,
+                       SLAP_SINGLE_SHADOW( si->si_be ) ? -1 : slap_serverID );
        } else {
                ldap_pvt_thread_mutex_lock( &si->si_cookieState->cs_mutex );
                /* match SIDs */
                if ( si->si_cookieState->cs_num > 1 && si->si_cookieAge !=
                        si->si_cookieState->cs_age ) {
-                       int i, j;
+                       int i, j, changed = 0;
 
                        for (i=0; !BER_BVISNULL( &si->si_syncCookie.ctxcsn[i] ); i++) {
                                /* bogus, just dup everything */
@@ -534,6 +535,7 @@ do_syncrep1(
                                        ber_bvarray_free( si->si_syncCookie.ctxcsn );
                                        ber_bvarray_dup_x( &si->si_syncCookie.ctxcsn,
                                                si->si_cookieState->cs_vals, NULL );
+                                       changed = 1;
                                        break;
                                }
                                for (j=0; j<si->si_cookieState->cs_num; j++) {
@@ -542,9 +544,16 @@ do_syncrep1(
                                                continue;
                                        ber_bvreplace( &si->si_syncCookie.ctxcsn[i],
                                                &si->si_cookieState->cs_vals[j] );
+                                       changed = 1;
                                        break;
                                }
                        }
+                       if ( changed ) {
+                               ch_free( si->si_syncCookie.octet_str.bv_val );
+                               slap_compose_sync_cookie( NULL, &si->si_syncCookie.octet_str,
+                                       si->si_syncCookie.ctxcsn, si->si_syncCookie.rid,
+                                       SLAP_SINGLE_SHADOW( si->si_be ) ? -1 : slap_serverID );
+                       }
                }
                ldap_pvt_thread_mutex_unlock( &si->si_cookieState->cs_mutex );
        }
@@ -1092,6 +1101,13 @@ reload:
                        goto reload;
                }
 
+               /* We got deleted while running on cn=config */
+               if ( !si->si_ctype ) {
+                       if ( si->si_conn_setup )
+                               dostop = 1;
+                       rc = -1;
+               }
+
                if ( abs(si->si_type) == LDAP_SYNC_REFRESH_AND_PERSIST ) {
                        /* If we succeeded, enable the connection for further listening.
                         * If we failed, tear down the connection and reschedule.
@@ -1146,7 +1162,8 @@ reload:
                                break;
                }
 
-               if ( !si->si_retrynum || si->si_retrynum[i] == RETRYNUM_TAIL ) {
+               if ( !si->si_ctype
+                       || !si->si_retrynum || si->si_retrynum[i] == RETRYNUM_TAIL ) {
                        ldap_pvt_runqueue_remove( &slapd_rq, rtask );
                } else if ( RETRYNUM_VALID( si->si_retrynum[i] ) ) {
                        if ( si->si_retrynum[i] > 0 )
@@ -1160,6 +1177,24 @@ reload:
        ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex );
        ldap_pvt_thread_mutex_unlock( &si->si_mutex );
 
+       /* Do final delete cleanup */
+       if ( !si->si_ctype ) {
+               cookie_state *cs = NULL;
+               syncinfo_t **sip;
+
+               cs = be->be_syncinfo->si_cookieState;
+               for ( sip = &be->be_syncinfo; *sip != si; sip = &(*sip)->si_next );
+               *sip = si->si_next;
+               syncinfo_free( si );
+               if ( !be->be_syncinfo ) {
+                       SLAP_DBFLAGS( be ) &= ~(SLAP_DBFLAG_SHADOW|SLAP_DBFLAG_SYNC_SHADOW);
+                       if ( cs ) {
+                               ber_bvarray_free( cs->cs_vals );
+                               ldap_pvt_thread_mutex_destroy( &cs->cs_mutex );
+                               ch_free( cs );
+                       }
+               }
+       }
        return NULL;
 }
 
@@ -3836,7 +3871,18 @@ syncrepl_config( ConfigArgs *c )
                                si = *sip;
                                if ( c->valx == -1 || i == c->valx ) {
                                        *sip = si->si_next;
-                                       syncinfo_free( si );
+                                       /* If the task is currently active, we have to leave
+                                        * it running. It will exit on its own. This will only
+                                        * happen when running on the cn=config DB.
+                                        */
+                                       if ( si->si_re &&
+                                               ldap_pvt_runqueue_isrunning( &slapd_rq, si->si_re ) ) {
+                                               si->si_ctype = 0;
+                                       } else {
+                                               syncinfo_free( si );
+                                       }
+                                       if ( i == c->valx )
+                                               break;
                                } else {
                                        sip = &si->si_next;
                                }