Diff for /servers/slapd/overlays/syncprov.c between versions 1.91 and 1.100

version 1.91, 2005/08/02 06:43:27 version 1.100, 2005/08/23 02:12:57
Line 1 Line 1
 /* $OpenLDAP: pkg/ldap/servers/slapd/overlays/syncprov.c,v 1.90 2005/07/18 04:22:36 hallvard Exp $ */  /* $OpenLDAP: pkg/ldap/servers/slapd/overlays/syncprov.c,v 1.99 2005/08/23 01:25:21 hyc Exp $ */
 /* syncprov.c - syncrepl provider */  /* syncprov.c - syncrepl provider */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.  /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *   *
Line 447  syncprov_findbase( Operation *op, fbase_ Line 447  syncprov_findbase( Operation *op, fbase_
  * was not checkpointed at the previous shutdown.   * was not checkpointed at the previous shutdown.
  *   *
  * 2: when the current contextCSN is known and we have a sync cookie, we search   * 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   * for one entry with CSN = the cookie CSN. If not found, try <= cookie CSN.
  * entry is found, the cookie CSN is valid, otherwise it is stale.   * If an entry is found, the cookie CSN is valid, otherwise it is stale.
  *   *
  * 3: 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   * CSN, and generate Present records for them. We always collect this result
Line 555  syncprov_findcsn( Operation *op, int mod Line 555  syncprov_findcsn( Operation *op, int mod
         int i, rc = LDAP_SUCCESS;          int i, rc = LDAP_SUCCESS;
         fpres_cookie pcookie;          fpres_cookie pcookie;
         sync_control *srs = NULL;          sync_control *srs = NULL;
           int findcsn_retry = 1;
   
         if ( mode != FIND_MAXCSN ) {          if ( mode != FIND_MAXCSN ) {
                 srs = op->o_controls[slap_cids.sc_LDAPsync];                  srs = op->o_controls[slap_cids.sc_LDAPsync];
Line 579  syncprov_findcsn( Operation *op, int mod Line 580  syncprov_findcsn( Operation *op, int mod
         fop.ors_filter = &cf;          fop.ors_filter = &cf;
         fop.ors_filterstr.bv_val = buf;          fop.ors_filterstr.bv_val = buf;
   
   again:
         switch( mode ) {          switch( mode ) {
         case FIND_MAXCSN:          case FIND_MAXCSN:
                 cf.f_choice = LDAP_FILTER_GE;                  cf.f_choice = LDAP_FILTER_GE;
Line 595  syncprov_findcsn( Operation *op, int mod Line 597  syncprov_findcsn( Operation *op, int mod
                 maxcsn.bv_len = si->si_ctxcsn.bv_len;                  maxcsn.bv_len = si->si_ctxcsn.bv_len;
                 break;                  break;
         case FIND_CSN:          case FIND_CSN:
                 cf.f_choice = LDAP_FILTER_LE;  
                 cf.f_av_value = srs->sr_state.ctxcsn;                  cf.f_av_value = srs->sr_state.ctxcsn;
                 fop.ors_filterstr.bv_len = sprintf( buf, "(entryCSN<=%s)",                  /* Look for exact match the first time */
                         cf.f_av_value.bv_val );                  if ( findcsn_retry ) {
                           cf.f_choice = LDAP_FILTER_EQUALITY;
                           fop.ors_filterstr.bv_len = sprintf( buf, "(entryCSN=%s)",
                                   cf.f_av_value.bv_val );
                   /* On retry, look for <= */
                   } else {
                           cf.f_choice = LDAP_FILTER_LE;
                           fop.ors_filterstr.bv_len = sprintf( buf, "(entryCSN<=%s)",
                                   cf.f_av_value.bv_val );
                   }
                 fop.ors_attrsonly = 1;                  fop.ors_attrsonly = 1;
                 fop.ors_attrs = slap_anlist_no_attrs;                  fop.ors_attrs = slap_anlist_no_attrs;
                 fop.ors_slimit = 1;                  fop.ors_slimit = 1;
Line 646  syncprov_findcsn( Operation *op, int mod Line 656  syncprov_findcsn( Operation *op, int mod
                 break;                  break;
         case FIND_CSN:          case FIND_CSN:
                 /* If matching CSN was not found, invalidate the context. */                  /* If matching CSN was not found, invalidate the context. */
                 if ( !cb.sc_private ) rc = LDAP_NO_SUCH_OBJECT;                  if ( !cb.sc_private ) {
                           /* If we didn't find an exact match, then try for <= */
                           if ( findcsn_retry ) {
                                   findcsn_retry = 0;
                                   goto again;
                           }
                           rc = LDAP_NO_SUCH_OBJECT;
                   }
                 break;                  break;
         case FIND_PRESENT:          case FIND_PRESENT:
                 op->o_tmpfree( pcookie.uuids, op->o_tmpmemctx );                  op->o_tmpfree( pcookie.uuids, op->o_tmpmemctx );
Line 1592  typedef struct searchstate { Line 1609  typedef struct searchstate {
         slap_overinst *ss_on;          slap_overinst *ss_on;
         syncops *ss_so;          syncops *ss_so;
         int ss_present;          int ss_present;
           struct berval ss_ctxcsn;
           char ss_csnbuf[LDAP_LUTIL_CSNSTR_BUFSIZE];
 } searchstate;  } searchstate;
   
 static int  static int
Line 1690  syncprov_search_response( Operation *op, Line 1709  syncprov_search_response( Operation *op,
         sync_control *srs = op->o_controls[slap_cids.sc_LDAPsync];          sync_control *srs = op->o_controls[slap_cids.sc_LDAPsync];
   
         if ( rs->sr_type == REP_SEARCH || rs->sr_type == REP_SEARCHREF ) {          if ( rs->sr_type == REP_SEARCH || rs->sr_type == REP_SEARCHREF ) {
                   Attribute *a;
                 /* If we got a referral without a referral object, there's                  /* If we got a referral without a referral object, there's
                  * something missing that we cannot replicate. Just ignore it.                   * something missing that we cannot replicate. Just ignore it.
                  * The consumer will abort because we didn't send the expected                   * The consumer will abort because we didn't send the expected
Line 1700  syncprov_search_response( Operation *op, Line 1720  syncprov_search_response( Operation *op,
                         Debug( LDAP_DEBUG_ANY, "bogus referral in context\n",0,0,0 );                          Debug( LDAP_DEBUG_ANY, "bogus referral in context\n",0,0,0 );
                         return SLAP_CB_CONTINUE;                          return SLAP_CB_CONTINUE;
                 }                  }
                 if ( !BER_BVISNULL( &srs->sr_state.ctxcsn )) {                  a = attr_find( rs->sr_entry->e_attrs, slap_schema.si_ad_entryCSN );
                         Attribute *a = attr_find( rs->sr_entry->e_attrs,                  if ( a ) {
                                 slap_schema.si_ad_entryCSN );                          /* Make sure entry is less than the snaphot'd contextCSN */
                                                   if ( ber_bvcmp( &a->a_nvals[0], &ss->ss_ctxcsn ) > 0 )
                                   return LDAP_SUCCESS;
   
                         /* Don't send the ctx entry twice */                          /* Don't send the ctx entry twice */
                         if ( a && bvmatch( &a->a_nvals[0], &srs->sr_state.ctxcsn ) )                          if ( !BER_BVISNULL( &srs->sr_state.ctxcsn ) &&
                                   bvmatch( &a->a_nvals[0], &srs->sr_state.ctxcsn ) )
                                 return LDAP_SUCCESS;                                  return LDAP_SUCCESS;
                 }                  }
                 rs->sr_ctrls = op->o_tmpalloc( sizeof(LDAPControl *)*2,                  rs->sr_ctrls = op->o_tmpalloc( sizeof(LDAPControl *)*2,
Line 1716  syncprov_search_response( Operation *op, Line 1739  syncprov_search_response( Operation *op,
         } else if ( rs->sr_type == REP_RESULT && rs->sr_err == LDAP_SUCCESS ) {          } else if ( rs->sr_type == REP_RESULT && rs->sr_err == LDAP_SUCCESS ) {
                 struct berval cookie;                  struct berval cookie;
   
                 slap_compose_sync_cookie( op, &cookie,                  slap_compose_sync_cookie( op, &cookie, &ss->ss_ctxcsn,
                         &op->ors_filter->f_and->f_ava->aa_value,  
                         srs->sr_state.rid );                          srs->sr_state.rid );
   
                 /* Is this a regular refresh? */                  /* Is this a regular refresh? */
Line 1763  syncprov_op_search( Operation *op, SlapR Line 1785  syncprov_op_search( Operation *op, SlapR
         syncprov_info_t         *si = (syncprov_info_t *)on->on_bi.bi_private;          syncprov_info_t         *si = (syncprov_info_t *)on->on_bi.bi_private;
         slap_callback   *cb;          slap_callback   *cb;
         int gotstate = 0, nochange = 0, do_present = 1;          int gotstate = 0, nochange = 0, do_present = 1;
         Filter *fand, *fava;  
         syncops *sop = NULL;          syncops *sop = NULL;
         searchstate *ss;          searchstate *ss;
         sync_control *srs;          sync_control *srs;
Line 1887  shortcut: Line 1908  shortcut:
                 sop->s_filterstr= op->ors_filterstr;                  sop->s_filterstr= op->ors_filterstr;
         }          }
   
         fand = op->o_tmpalloc( sizeof(Filter), op->o_tmpmemctx );          /* If something changed, find the changes */
         fand->f_choice = LDAP_FILTER_AND;          if ( gotstate && !nochange ) {
         fand->f_next = NULL;                  Filter *fand, *fava;
         fava = op->o_tmpalloc( sizeof(Filter), op->o_tmpmemctx );  
         fava->f_choice = LDAP_FILTER_LE;                  fand = op->o_tmpalloc( sizeof(Filter), op->o_tmpmemctx );
         fava->f_ava = op->o_tmpalloc( sizeof(AttributeAssertion), op->o_tmpmemctx );                  fand->f_choice = LDAP_FILTER_AND;
         fava->f_ava->aa_desc = slap_schema.si_ad_entryCSN;                  fand->f_next = NULL;
 #ifdef LDAP_COMP_MATCH                  fava = op->o_tmpalloc( sizeof(Filter), op->o_tmpmemctx );
         fava->f_ava->aa_cf = NULL;                  fand->f_and = fava;
 #endif  
         ber_dupbv_x( &fava->f_ava->aa_value, &ctxcsn, op->o_tmpmemctx );  
         fand->f_and = fava;  
         if ( gotstate ) {  
                 fava->f_next = op->o_tmpalloc( sizeof(Filter), op->o_tmpmemctx );  
                 fava = fava->f_next;  
                 fava->f_choice = LDAP_FILTER_GE;                  fava->f_choice = LDAP_FILTER_GE;
                 fava->f_ava = op->o_tmpalloc( sizeof(AttributeAssertion), op->o_tmpmemctx );                  fava->f_ava = op->o_tmpalloc( sizeof(AttributeAssertion), op->o_tmpmemctx );
                 fava->f_ava->aa_desc = slap_schema.si_ad_entryCSN;                  fava->f_ava->aa_desc = slap_schema.si_ad_entryCSN;
Line 1909  shortcut: Line 1924  shortcut:
                 fava->f_ava->aa_cf = NULL;                  fava->f_ava->aa_cf = NULL;
 #endif  #endif
                 ber_dupbv_x( &fava->f_ava->aa_value, &srs->sr_state.ctxcsn, op->o_tmpmemctx );                  ber_dupbv_x( &fava->f_ava->aa_value, &srs->sr_state.ctxcsn, op->o_tmpmemctx );
                   fava->f_next = op->ors_filter;
                   op->ors_filter = fand;
                   filter2bv_x( op, op->ors_filter, &op->ors_filterstr );
         }          }
         fava->f_next = op->ors_filter;  
         op->ors_filter = fand;  
         filter2bv_x( op, op->ors_filter, &op->ors_filterstr );  
   
         /* Let our callback add needed info to returned entries */          /* Let our callback add needed info to returned entries */
         cb = op->o_tmpcalloc(1, sizeof(slap_callback)+sizeof(searchstate), op->o_tmpmemctx);          cb = op->o_tmpcalloc(1, sizeof(slap_callback)+sizeof(searchstate), op->o_tmpmemctx);
Line 1920  shortcut: Line 1935  shortcut:
         ss->ss_on = on;          ss->ss_on = on;
         ss->ss_so = sop;          ss->ss_so = sop;
         ss->ss_present = do_present;          ss->ss_present = do_present;
           ss->ss_ctxcsn.bv_len = ctxcsn.bv_len;
           ss->ss_ctxcsn.bv_val = ss->ss_csnbuf;
           strcpy( ss->ss_ctxcsn.bv_val, ctxcsn.bv_val );
         cb->sc_response = syncprov_search_response;          cb->sc_response = syncprov_search_response;
         cb->sc_cleanup = syncprov_search_cleanup;          cb->sc_cleanup = syncprov_search_cleanup;
         cb->sc_private = ss;          cb->sc_private = ss;
Line 2000  static ConfigTable spcfg[] = { Line 2018  static ConfigTable spcfg[] = {
                 sp_cf_gen, "( OLcfgOvAt:1.1 NAME 'olcSpCheckpoint' "                  sp_cf_gen, "( OLcfgOvAt:1.1 NAME 'olcSpCheckpoint' "
                         "DESC 'ContextCSN checkpoint interval in ops and minutes' "                          "DESC 'ContextCSN checkpoint interval in ops and minutes' "
                         "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },                          "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
         { "syncprov-sessionlog", "size", 2, 2, 0, ARG_INT|ARG_MAGIC|SP_SESSL,          { "syncprov-sessionlog", "ops", 2, 2, 0, ARG_INT|ARG_MAGIC|SP_SESSL,
                 sp_cf_gen, "( OLcfgOvAt:1.2 NAME 'olcSpSessionlog' "                  sp_cf_gen, "( OLcfgOvAt:1.2 NAME 'olcSpSessionlog' "
                         "DESC 'Session log size in ops' "                          "DESC 'Session log size in ops' "
                         "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },                          "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
Line 2093  sp_cf_gen(ConfigArgs *c) Line 2111  sp_cf_gen(ConfigArgs *c)
         return rc;          return rc;
 }  }
   
 /* Cheating - we have no thread pool context for these functions,  
  * so make one.  
  */  
 typedef struct thread_keys {  
         void *key;  
         void *data;  
         ldap_pvt_thread_pool_keyfree_t *xfree;  
 } thread_keys;  
   
 #define MAXKEYS 32  
 /* A fake thread context */  
 static thread_keys thrctx[MAXKEYS];  
   
 /* ITS#3456 we cannot run this search on the main thread, must use a  /* ITS#3456 we cannot run this search on the main thread, must use a
  * child thread in order to insure we have a big enough stack.   * child thread in order to insure we have a big enough stack.
  */   */
Line 2137  syncprov_db_open( Line 2142  syncprov_db_open(
         Entry *e;          Entry *e;
         Attribute *a;          Attribute *a;
         int rc;          int rc;
           void *thrctx = NULL;
   
         if ( slapMode & SLAP_TOOL_MODE ) {          if ( slapMode & SLAP_TOOL_MODE ) {
                 return 0;                  return 0;
Line 2147  syncprov_db_open( Line 2153  syncprov_db_open(
                 return rc;                  return rc;
         }          }
   
           thrctx = ldap_pvt_thread_pool_context();
         connection_fake_init( &conn, op, thrctx );          connection_fake_init( &conn, op, thrctx );
         op->o_bd = be;          op->o_bd = be;
         op->o_dn = be->be_rootdn;          op->o_dn = be->be_rootdn;
Line 2200  syncprov_db_open( Line 2207  syncprov_db_open(
   
 out:  out:
         op->o_bd->bd_info = (BackendInfo *)on;          op->o_bd->bd_info = (BackendInfo *)on;
           ldap_pvt_thread_pool_context_reset( thrctx );
         return 0;          return 0;
 }  }
   
Line 2222  syncprov_db_close( Line 2230  syncprov_db_close(
                 char opbuf[OPERATION_BUFFER_SIZE];                  char opbuf[OPERATION_BUFFER_SIZE];
                 Operation *op = (Operation *)opbuf;                  Operation *op = (Operation *)opbuf;
                 SlapReply rs = {REP_RESULT};                  SlapReply rs = {REP_RESULT};
                   void *thrctx;
   
                   thrctx = ldap_pvt_thread_pool_context();
                 connection_fake_init( &conn, op, thrctx );                  connection_fake_init( &conn, op, thrctx );
                 op->o_bd = be;                  op->o_bd = be;
                 op->o_dn = be->be_rootdn;                  op->o_dn = be->be_rootdn;
                 op->o_ndn = be->be_rootndn;                  op->o_ndn = be->be_rootndn;
                 syncprov_checkpoint( op, &rs, on );                  syncprov_checkpoint( op, &rs, on );
         }                  ldap_pvt_thread_pool_context_reset( thrctx );
         for ( i=0; thrctx[i].key; i++) {  
                 if ( thrctx[i].xfree )  
                         thrctx[i].xfree( thrctx[i].key, thrctx[i].data );  
                 thrctx[i].key = NULL;  
         }          }
   
     return 0;      return 0;
Line 2286  static int syncprov_parseCtrl ( Line 2292  static int syncprov_parseCtrl (
         LDAPControl *ctrl )          LDAPControl *ctrl )
 {  {
         ber_tag_t tag;          ber_tag_t tag;
         BerElement *ber;          BerElementBuffer berbuf;
           BerElement *ber = (BerElement *)&berbuf;
         ber_int_t mode;          ber_int_t mode;
         ber_len_t len;          ber_len_t len;
         struct berval cookie = BER_BVNULL;          struct berval cookie = BER_BVNULL;
Line 2320  static int syncprov_parseCtrl ( Line 2327  static int syncprov_parseCtrl (
          *      }           *      }
          */           */
   
         ber = ber_init( &ctrl->ldctl_value );          ber_init2( ber, &ctrl->ldctl_value, 0 );
         if( ber == NULL ) {  
                 rs->sr_text = "internal error";  
                 return LDAP_OTHER;  
         }  
   
         if ( (tag = ber_scanf( ber, "{i" /*}*/, &mode )) == LBER_ERROR ) {          if ( (tag = ber_scanf( ber, "{i" /*}*/, &mode )) == LBER_ERROR ) {
                 rs->sr_text = "Sync control : mode decoding error";                  rs->sr_text = "Sync control : mode decoding error";
Line 2346  static int syncprov_parseCtrl ( Line 2349  static int syncprov_parseCtrl (
         tag = ber_peek_tag( ber, &len );          tag = ber_peek_tag( ber, &len );
   
         if ( tag == LDAP_TAG_SYNC_COOKIE ) {          if ( tag == LDAP_TAG_SYNC_COOKIE ) {
                 if (( ber_scanf( ber, /*{*/ "o", &cookie )) == LBER_ERROR ) {                  if (( ber_scanf( ber, /*{*/ "m", &cookie )) == LBER_ERROR ) {
                         rs->sr_text = "Sync control : cookie decoding error";                          rs->sr_text = "Sync control : cookie decoding error";
                         return LDAP_PROTOCOL_ERROR;                          return LDAP_PROTOCOL_ERROR;
                 }                  }
Line 2364  static int syncprov_parseCtrl ( Line 2367  static int syncprov_parseCtrl (
         sr = op->o_tmpcalloc( 1, sizeof(struct sync_control), op->o_tmpmemctx );          sr = op->o_tmpcalloc( 1, sizeof(struct sync_control), op->o_tmpmemctx );
         sr->sr_rhint = rhint;          sr->sr_rhint = rhint;
         if (!BER_BVISNULL(&cookie)) {          if (!BER_BVISNULL(&cookie)) {
                 ber_dupbv( &sr->sr_state.octet_str, &cookie );                  ber_dupbv_x( &sr->sr_state.octet_str, &cookie, op->o_tmpmemctx );
                 slap_parse_sync_cookie( &sr->sr_state );                  slap_parse_sync_cookie( &sr->sr_state, op->o_tmpmemctx );
                   if ( sr->sr_state.rid == -1 ) {
                           rs->sr_text = "Sync control : cookie parsing error";
                           return LDAP_PROTOCOL_ERROR;
                   }
         }          }
   
         op->o_controls[slap_cids.sc_LDAPsync] = sr;          op->o_controls[slap_cids.sc_LDAPsync] = sr;
   
         (void) ber_free( ber, 1 );  
   
         op->o_sync = ctrl->ldctl_iscritical          op->o_sync = ctrl->ldctl_iscritical
                 ? SLAP_CONTROL_CRITICAL                  ? SLAP_CONTROL_CRITICAL
                 : SLAP_CONTROL_NONCRITICAL;                  : SLAP_CONTROL_NONCRITICAL;

Removed from v.1.91  
changed lines
  Added in v.1.100


______________
© Copyright 1998-2020, OpenLDAP Foundation, info@OpenLDAP.org