]> git.sur5r.net Git - openldap/commitdiff
Restored findcsn( MAX ), used at db_open time
authorHoward Chu <hyc@openldap.org>
Sun, 5 Dec 2004 20:52:49 +0000 (20:52 +0000)
committerHoward Chu <hyc@openldap.org>
Sun, 5 Dec 2004 20:52:49 +0000 (20:52 +0000)
servers/slapd/overlays/syncprov.c

index aed476f14f6dc18a0d22e9de74abb1e4005c5d29..d119dba76cd83c3a068f14b56f9373c61ba859f6 100644 (file)
@@ -478,18 +478,39 @@ syncprov_findbase( Operation *op, fbase_cookie *fc )
 }
 
 /* syncprov_findcsn:
- *   This function has two different purposes, but they both use a search
+ *   This function has three different purposes, but they all use a search
  * that filters on entryCSN so they're combined here.
- * 1: when the current contextCSN is known and we have a sync cookie, we search
+ * 1: at startup time, after a contextCSN has been read from the database,
+ * we search for all entries with CSN >= contextCSN in case the contextCSN
+ * was not checkpointed at the previous shutdown.
+ *
+ * 2: when the current contextCSN is known and we have a sync cookie, we search
  * for one entry with CSN <= the cookie CSN. (Used to search for =.) If an
  * entry is found, the cookie CSN is valid, otherwise it is stale.
  *
- * 2: during a refresh phase, we search for all entries with CSN <= the cookie
+ * 3: during a refresh phase, we search for all entries with CSN <= the cookie
  * CSN, and generate Present records for them. We always collect this result
  * in SyncID sets, even if there's only one match.
  */
-#define        FIND_CSN        1
-#define        FIND_PRESENT    2
+#define        FIND_MAXCSN     1
+#define        FIND_CSN        2
+#define        FIND_PRESENT    3
+
+static int
+findmax_cb( Operation *op, SlapReply *rs )
+{
+       if ( rs->sr_type == REP_SEARCH && rs->sr_err == LDAP_SUCCESS ) {
+               struct berval *maxcsn = op->o_callback->sc_private;
+               Attribute *a = attr_find( rs->sr_entry->e_attrs,
+                       slap_schema.si_ad_entryCSN );
+
+               if ( a && ber_bvcmp( &a->a_vals[0], maxcsn )) {
+                       maxcsn->bv_len = a->a_vals[0].bv_len;
+                       strcpy( maxcsn->bv_val, a->a_vals[0].bv_val );
+               }
+       }
+       return LDAP_SUCCESS;
+}
 
 static int
 findcsn_cb( Operation *op, SlapReply *rs )
@@ -556,30 +577,60 @@ syncprov_findcsn( Operation *op, int mode )
        SlapReply frs = { REP_RESULT };
        char buf[LDAP_LUTIL_CSNSTR_BUFSIZE + STRLENOF("(entryCSN<=)")];
        char cbuf[LDAP_LUTIL_CSNSTR_BUFSIZE];
-       struct berval fbuf;
+       struct berval fbuf, maxcsn;
        Filter cf;
        AttributeAssertion eq;
-       int rc;
+       int rc = LDAP_SUCCESS;
        fpres_cookie pcookie;
        int locked = 0;
-       sync_control *srs = op->o_controls[slap_cids.sc_LDAPsync];
+       sync_control *srs;
 
-       if ( srs->sr_state.ctxcsn->bv_len >= LDAP_LUTIL_CSNSTR_BUFSIZE ) {
-               return LDAP_OTHER;
+       if ( mode != FIND_MAXCSN ) {
+               srs = op->o_controls[slap_cids.sc_LDAPsync];
+
+               if ( srs->sr_state.ctxcsn->bv_len >= LDAP_LUTIL_CSNSTR_BUFSIZE ) {
+                       return LDAP_OTHER;
+               }
        }
 
        fop = *op;
        fop.o_sync_mode &= SLAP_CONTROL_MASK;   /* turn off sync_mode */
 
        fbuf.bv_val = buf;
-       if ( mode == FIND_CSN ) {
+       cf.f_ava = &eq;
+       cf.f_av_desc = slap_schema.si_ad_entryCSN;
+       cf.f_next = NULL;
+
+       switch( mode ) {
+       case FIND_MAXCSN:
+               cf.f_choice = LDAP_FILTER_GE;
+               cf.f_av_value = si->si_ctxcsn;
+               fbuf.bv_len = sprintf( buf, "(entryCSN>=%s)",
+                       cf.f_av_value.bv_val );
+               fop.ors_attrsonly = 0;
+               fop.ors_attrs = csn_anlist;
+               fop.ors_slimit = SLAP_NO_LIMIT;
+               cb.sc_private = &maxcsn;
+               cb.sc_response = findmax_cb;
+               maxcsn.bv_val = cbuf;
+               maxcsn.bv_len = 0;
+               break;
+       case FIND_CSN:
+               cf.f_choice = LDAP_FILTER_LE;
+               cf.f_av_value = *srs->sr_state.ctxcsn;
+               fbuf.bv_len = sprintf( buf, "(entryCSN<=%s)",
+                       cf.f_av_value.bv_val );
                fop.ors_attrsonly = 1;
                fop.ors_attrs = slap_anlist_no_attrs;
                fop.ors_slimit = 1;
                cb.sc_private = NULL;
                cb.sc_response = findcsn_cb;
-
-       } else if ( mode == FIND_PRESENT ) {
+               break;
+       case FIND_PRESENT:
+               cf.f_choice = LDAP_FILTER_LE;
+               cf.f_av_value = *srs->sr_state.ctxcsn;
+               fbuf.bv_len = sprintf( buf, "(entryCSN<=%s)",
+                       cf.f_av_value.bv_val );
                fop.ors_attrsonly = 0;
                fop.ors_attrs = uuid_anlist;
                fop.ors_slimit = SLAP_NO_LIMIT;
@@ -589,15 +640,8 @@ syncprov_findcsn( Operation *op, int mode )
                cb.sc_response = findpres_cb;
                pcookie.num = 0;
                pcookie.uuids = NULL;
+               break;
        }
-       cf.f_choice = LDAP_FILTER_LE;
-       cf.f_ava = &eq;
-       cf.f_av_desc = slap_schema.si_ad_entryCSN;
-       cf.f_av_value = *srs->sr_state.ctxcsn;
-       cf.f_next = NULL;
-       fbuf.bv_len = sprintf( buf, "(entryCSN<=%s)",
-               srs->sr_state.ctxcsn->bv_val );
-
        fop.o_callback = &cb;
        fop.ors_limit = NULL;
        fop.ors_tlimit = SLAP_NO_LIMIT;
@@ -605,17 +649,25 @@ syncprov_findcsn( Operation *op, int mode )
        fop.ors_filterstr = fbuf;
 
        fop.o_bd->bd_info = on->on_info->oi_orig;
-       rc = fop.o_bd->be_search( &fop, &frs );
+       fop.o_bd->be_search( &fop, &frs );
        fop.o_bd->bd_info = (BackendInfo *)on;
 
-       if ( mode == FIND_CSN ) {
-               if ( cb.sc_private ) return LDAP_SUCCESS;
-       } else if ( mode == FIND_PRESENT ) {
-               return LDAP_SUCCESS;
+       switch( mode ) {
+       case FIND_MAXCSN:
+               if ( maxcsn.bv_len ) {
+                       strcpy( si->si_ctxcsnbuf, maxcsn.bv_val );
+                       si->si_ctxcsn.bv_len = maxcsn.bv_len;
+               }
+               break;
+       case FIND_CSN:
+               /* If matching CSN was not found, invalidate the context. */
+               if ( !cb.sc_private ) rc = LDAP_NO_SUCH_OBJECT;
+               break;
+       case FIND_PRESENT:
+               break;
        }
 
-       /* If matching CSN was not found, invalidate the context. */
-       return LDAP_NO_SUCH_OBJECT;
+       return rc;
 }
 
 /* Queue a persistent search response if still in Refresh stage */
@@ -1633,19 +1685,17 @@ syncprov_db_open(
        slap_overinst   *on = (slap_overinst *) be->bd_info;
        syncprov_info_t *si = (syncprov_info_t *)on->on_bi.bi_private;
 
+       Connection conn;
        char opbuf[OPERATION_BUFFER_SIZE];
        Operation *op = (Operation *)opbuf;
        Entry *e;
        Attribute *a;
        int rc;
 
-       memset(opbuf, 0, sizeof(opbuf));
-       op->o_hdr = (Opheader *)(op+1);
+       connection_fake_init( &conn, op, thrctx );
        op->o_bd = be;
        op->o_dn = be->be_rootdn;
        op->o_ndn = be->be_rootndn;
-       op->o_threadctx = thrctx;
-       op->o_tmpmfuncs = &ch_mfuncs;
 
        op->o_bd->bd_info = on->on_info->oi_orig;
        rc = be_entry_get_rw( op, be->be_nsuffix, NULL,
@@ -1662,6 +1712,11 @@ syncprov_db_open(
                        si->si_ctxcsnbuf[si->si_ctxcsn.bv_len] = '\0';
                }
                be_entry_release_r( op, e );
+               op->o_bd->bd_info = (BackendInfo *)on;
+               op->o_req_dn = be->be_suffix[0];
+               op->o_req_ndn = be->be_nsuffix[0];
+               op->ors_scope = LDAP_SCOPE_SUBTREE;
+               syncprov_findcsn( op, FIND_MAXCSN );
        }
 
        if ( BER_BVISEMPTY( &si->si_ctxcsn ) ) {