Diff for /servers/slapd/overlays/syncprov.c between versions 1.147.2.11 and 1.224

version 1.147.2.11, 2007/10/18 01:35:12 version 1.224, 2008/03/20 23:09:24
Line 1 Line 1
 /* $OpenLDAP: pkg/ldap/servers/slapd/overlays/syncprov.c,v 1.147.2.10 2007/09/29 09:55:22 hyc Exp $ */  /* $OpenLDAP: pkg/ldap/servers/slapd/overlays/syncprov.c,v 1.223 2008/03/19 23:31:42 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/>.
  *   *
  * Copyright 2004-2007 The OpenLDAP Foundation.   * Copyright 2004-2008 The OpenLDAP Foundation.
  * All rights reserved.   * All rights reserved.
  *   *
  * Redistribution and use in source and binary forms, with or without   * Redistribution and use in source and binary forms, with or without
Line 624  again: Line 624  again:
                                 maxid = i;                                  maxid = i;
                         }                          }
                 }                  }
                 fop.ors_filterstr.bv_len = sprintf( buf, "(entryCSN>=%s)",                  fop.ors_filterstr.bv_len = snprintf( buf, sizeof( buf ),
                         cf.f_av_value.bv_val );                          "(entryCSN>=%s)", cf.f_av_value.bv_val );
                   if ( fop.ors_filterstr.bv_len < 0 || fop.ors_filterstr.bv_len >= sizeof( buf ) ) {
                           return LDAP_OTHER;
                   }
                 fop.ors_attrsonly = 0;                  fop.ors_attrsonly = 0;
                 fop.ors_attrs = csn_anlist;                  fop.ors_attrs = csn_anlist;
                 fop.ors_slimit = SLAP_NO_LIMIT;                  fop.ors_slimit = SLAP_NO_LIMIT;
Line 649  again: Line 652  again:
                 /* Look for exact match the first time */                  /* Look for exact match the first time */
                 if ( findcsn_retry ) {                  if ( findcsn_retry ) {
                         cf.f_choice = LDAP_FILTER_EQUALITY;                          cf.f_choice = LDAP_FILTER_EQUALITY;
                         fop.ors_filterstr.bv_len = sprintf( buf, "(entryCSN=%s)",                          fop.ors_filterstr.bv_len = snprintf( buf, sizeof( buf ),
                                 cf.f_av_value.bv_val );                                  "(entryCSN=%s)", cf.f_av_value.bv_val );
                 /* On retry, look for <= */                  /* On retry, look for <= */
                 } else {                  } else {
                         cf.f_choice = LDAP_FILTER_LE;                          cf.f_choice = LDAP_FILTER_LE;
                         fop.ors_limit = &fc_limits;                          fop.ors_limit = &fc_limits;
                         memset( &fc_limits, 0, sizeof( fc_limits ));                          memset( &fc_limits, 0, sizeof( fc_limits ));
                         fc_limits.lms_s_unchecked = 1;                          fc_limits.lms_s_unchecked = 1;
                         fop.ors_filterstr.bv_len = sprintf( buf, "(entryCSN<=%s)",                          fop.ors_filterstr.bv_len = snprintf( buf, sizeof( buf ),
                                 cf.f_av_value.bv_val );                                  "(entryCSN<=%s)", cf.f_av_value.bv_val );
                   }
                   if ( fop.ors_filterstr.bv_len < 0 || fop.ors_filterstr.bv_len >= sizeof( buf ) ) {
                           return LDAP_OTHER;
                 }                  }
                 fop.ors_attrsonly = 1;                  fop.ors_attrsonly = 1;
                 fop.ors_attrs = slap_anlist_no_attrs;                  fop.ors_attrs = slap_anlist_no_attrs;
Line 690  again: Line 696  again:
                 break;                  break;
         }          }
   
         fop.o_bd->bd_info = on->on_info->oi_orig;          if ( on->on_next )
                   fop.o_bd->bd_info = (BackendInfo *)on->on_next;
           else
                   fop.o_bd->bd_info = on->on_info->oi_orig;
         fop.o_bd->be_search( &fop, &frs );          fop.o_bd->be_search( &fop, &frs );
         fop.o_bd->bd_info = (BackendInfo *)on;          fop.o_bd->bd_info = (BackendInfo *)on;
   
Line 831  syncprov_sendresp( Operation *op, opcook Line 840  syncprov_sendresp( Operation *op, opcook
   
 /* Play back queued responses */  /* Play back queued responses */
 static int  static int
 syncprov_qplay( Operation *op, slap_overinst *on, syncops *so )  syncprov_qplay( Operation *op, struct re_s *rtask )
 {  {
           syncops *so = rtask->arg;
           slap_overinst *on = LDAP_SLIST_FIRST(&so->s_op->o_extra)->oe_key;
         syncres *sr;          syncres *sr;
         Entry *e;          Entry *e;
         opcookie opc;          opcookie opc;
Line 847  syncprov_qplay( Operation *op, slap_over Line 858  syncprov_qplay( Operation *op, slap_over
                         so->s_res = sr->s_next;                          so->s_res = sr->s_next;
                 if ( !so->s_res )                  if ( !so->s_res )
                         so->s_restail = NULL;                          so->s_restail = NULL;
                 ldap_pvt_thread_mutex_unlock( &so->s_mutex );                  /* Exit loop with mutex held */
   
                 if ( !sr || so->s_op->o_abandon )                  if ( !sr || so->s_op->o_abandon )
                         break;                          break;
                   ldap_pvt_thread_mutex_unlock( &so->s_mutex );
   
                 opc.sdn = sr->s_dn;                  opc.sdn = sr->s_dn;
                 opc.sndn = sr->s_ndn;                  opc.sndn = sr->s_ndn;
Line 877  syncprov_qplay( Operation *op, slap_over Line 888  syncprov_qplay( Operation *op, slap_over
   
                 ch_free( sr );                  ch_free( sr );
   
                 if ( rc )                  if ( rc ) {
                           /* Exit loop with mutex held */
                           ldap_pvt_thread_mutex_lock( &so->s_mutex );
                         break;                          break;
                   }
         }          }
   
           /* wait until we get explicitly scheduled again */
           ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex );
           ldap_pvt_runqueue_stoptask( &slapd_rq, rtask );
           if ( rc == 0 ) {
                   ldap_pvt_runqueue_resched( &slapd_rq, rtask, 1 );
           } else {
                   /* bail out on any error */
                   ldap_pvt_runqueue_remove( &slapd_rq, rtask );
           }
           ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex );
           ldap_pvt_thread_mutex_unlock( &so->s_mutex );
         return rc;          return rc;
 }  }
   
Line 889  syncprov_qtask( void *ctx, void *arg ) Line 915  syncprov_qtask( void *ctx, void *arg )
 {  {
         struct re_s *rtask = arg;          struct re_s *rtask = arg;
         syncops *so = rtask->arg;          syncops *so = rtask->arg;
         slap_overinst *on = so->s_op->o_private;  
         OperationBuffer opbuf;          OperationBuffer opbuf;
         Operation *op;          Operation *op;
         BackendDB be;          BackendDB be;
Line 911  syncprov_qtask( void *ctx, void *arg ) Line 936  syncprov_qtask( void *ctx, void *arg )
         be = *so->s_op->o_bd;          be = *so->s_op->o_bd;
         be.be_flags |= SLAP_DBFLAG_OVERLAY;          be.be_flags |= SLAP_DBFLAG_OVERLAY;
         op->o_bd = &be;          op->o_bd = &be;
         op->o_private = NULL;          LDAP_SLIST_FIRST(&op->o_extra) = NULL;
         op->o_callback = NULL;          op->o_callback = NULL;
   
         rc = syncprov_qplay( op, on, so );          rc = syncprov_qplay( op, rtask );
   
         /* decrement use count... */          /* decrement use count... */
         syncprov_free_syncop( so );          syncprov_free_syncop( so );
   
         /* wait until we get explicitly scheduled again */  
         ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex );  
         ldap_pvt_runqueue_stoptask( &slapd_rq, rtask );  
         if ( rc == 0 ) {  
                 ldap_pvt_runqueue_resched( &slapd_rq, rtask, 1 );  
         } else {  
                 /* bail out on any error */  
                 ldap_pvt_runqueue_remove( &slapd_rq, rtask );  
         }  
         ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex );  
   
 #if 0   /* FIXME: connection_close isn't exported from slapd.  #if 0   /* FIXME: connection_close isn't exported from slapd.
                  * should it be?                   * should it be?
                  */                   */
Line 1203  syncprov_matchops( Operation *op, opcook Line 1217  syncprov_matchops( Operation *op, opcook
                 }                  }
   
                 /* check if current o_req_dn is in scope and matches filter */                  /* check if current o_req_dn is in scope and matches filter */
                 if ( fc.fscope && test_filter( op, e, ss->s_op->ors_filter ) ==                  if ( fc.fscope && test_filter( ss->s_op, e, ss->s_op->ors_filter ) ==
                         LDAP_COMPARE_TRUE ) {                          LDAP_COMPARE_TRUE ) {
                         if ( saveit ) {                          if ( saveit ) {
                                 sm = op->o_tmpalloc( sizeof(syncmatches), op->o_tmpmemctx );                                  sm = op->o_tmpalloc( sizeof(syncmatches), op->o_tmpmemctx );
Line 1295  syncprov_checkpoint( Operation *op, Slap Line 1309  syncprov_checkpoint( Operation *op, Slap
         Operation opm;          Operation opm;
         SlapReply rsm = { 0 };          SlapReply rsm = { 0 };
         slap_callback cb = {0};          slap_callback cb = {0};
           BackendDB be;
   
         mod.sml_numvals = si->si_numcsns;          mod.sml_numvals = si->si_numcsns;
         mod.sml_values = si->si_ctxcsn;          mod.sml_values = si->si_ctxcsn;
Line 1310  syncprov_checkpoint( Operation *op, Slap Line 1325  syncprov_checkpoint( Operation *op, Slap
         opm.o_callback = &cb;          opm.o_callback = &cb;
         opm.orm_modlist = &mod;          opm.orm_modlist = &mod;
         opm.orm_no_opattrs = 1;          opm.orm_no_opattrs = 1;
         opm.o_req_dn = op->o_bd->be_suffix[0];          if ( SLAP_GLUE_SUBORDINATE( op->o_bd )) {
         opm.o_req_ndn = op->o_bd->be_nsuffix[0];                  be = *on->on_info->oi_origdb;
                   opm.o_bd = &be;
           }
           opm.o_req_dn = opm.o_bd->be_suffix[0];
           opm.o_req_ndn = opm.o_bd->be_nsuffix[0];
         opm.o_bd->bd_info = on->on_info->oi_orig;          opm.o_bd->bd_info = on->on_info->oi_orig;
         opm.o_managedsait = SLAP_CONTROL_NONCRITICAL;          opm.o_managedsait = SLAP_CONTROL_NONCRITICAL;
         opm.o_no_schema_check = 1;          opm.o_no_schema_check = 1;
Line 1319  syncprov_checkpoint( Operation *op, Slap Line 1338  syncprov_checkpoint( Operation *op, Slap
         if ( mod.sml_next != NULL ) {          if ( mod.sml_next != NULL ) {
                 slap_mods_free( mod.sml_next, 1 );                  slap_mods_free( mod.sml_next, 1 );
         }          }
         opm.orm_no_opattrs = 0;  
 }  }
   
 static void  static void
Line 1513  syncprov_playlog( Operation *op, SlapRep Line 1531  syncprov_playlog( Operation *op, SlapRep
                 fop.ors_filter = &af;                  fop.ors_filter = &af;
   
                 cb.sc_response = playlog_cb;                  cb.sc_response = playlog_cb;
                 fop.o_bd->bd_info = on->on_info->oi_orig;                  if ( on->on_next )
                           fop.o_bd->bd_info = (BackendInfo *)on->on_next;
                   else
                           fop.o_bd->bd_info = on->on_info->oi_orig;
   
                 for ( i=ndel; i<num; i++ ) {                  for ( i=ndel; i<num; i++ ) {
                         if ( uuids[i].bv_len == 0 ) continue;                          if ( uuids[i].bv_len == 0 ) continue;
Line 1534  syncprov_playlog( Operation *op, SlapRep Line 1555  syncprov_playlog( Operation *op, SlapRep
         if ( ndel ) {          if ( ndel ) {
                 struct berval cookie;                  struct berval cookie;
   
                 slap_compose_sync_cookie( op, &cookie, delcsn, srs->sr_state.rid,                  if ( delcsn[0].bv_len ) {
                         srs->sr_state.sid );                          slap_compose_sync_cookie( op, &cookie, delcsn, srs->sr_state.rid,
                                   srs->sr_state.sid );
                   }
   
                 Debug( LDAP_DEBUG_SYNC, "syncprov_playlog: cookie=%s\n", cookie.bv_val, 0, 0 );                  Debug( LDAP_DEBUG_SYNC, "syncprov_playlog: cookie=%s\n", cookie.bv_val, 0, 0 );
   
                 uuids[ndel].bv_val = NULL;                  uuids[ndel].bv_val = NULL;
                 syncprov_sendinfo( op, rs, LDAP_TAG_SYNC_ID_SET, &cookie, 0, uuids, 1 );                  syncprov_sendinfo( op, rs, LDAP_TAG_SYNC_ID_SET,
                           delcsn[0].bv_len ? &cookie : NULL, 0, uuids, 1 );
                 op->o_tmpfree( cookie.bv_val, op->o_tmpmemctx );                  op->o_tmpfree( cookie.bv_val, op->o_tmpmemctx );
         }          }
         op->o_tmpfree( uuids, op->o_tmpmemctx );          op->o_tmpfree( uuids, op->o_tmpmemctx );
Line 1601  syncprov_op_response( Operation *op, Sla Line 1625  syncprov_op_response( Operation *op, Sla
                         }                          }
                         if ( si->si_chktime &&                          if ( si->si_chktime &&
                                 (op->o_time - si->si_chklast >= si->si_chktime )) {                                  (op->o_time - si->si_chklast >= si->si_chktime )) {
                                 do_check = 1;                                  if ( si->si_chklast ) {
                                 si->si_chklast = op->o_time;                                          do_check = 1;
                                           si->si_chklast = op->o_time;
                                   } else {
                                           si->si_chklast = 1;
                                   }
                         }                          }
                 }                  }
                 ldap_pvt_thread_rdwr_wunlock( &si->si_csn_rwlock );                  ldap_pvt_thread_rdwr_wunlock( &si->si_csn_rwlock );
Line 1765  syncprov_op_mod( Operation *op, SlapRepl Line 1793  syncprov_op_mod( Operation *op, SlapRepl
                         /* wait for this op to get to head of list */                          /* wait for this op to get to head of list */
                         while ( mt->mt_mods != mi ) {                          while ( mt->mt_mods != mi ) {
                                 ldap_pvt_thread_mutex_unlock( &mt->mt_mutex );                                  ldap_pvt_thread_mutex_unlock( &mt->mt_mutex );
                                 ldap_pvt_thread_yield();                                  /* FIXME: if dynamic config can delete overlays or
                                    * databases we'll have to check for cleanup here.
                                    * Currently it's not an issue because there are
                                    * no dynamic config deletes...
                                    */
                                   if ( !ldap_pvt_thread_pool_pausecheck( &connection_pool ))
                                           ldap_pvt_thread_yield();
                                 ldap_pvt_thread_mutex_lock( &mt->mt_mutex );                                  ldap_pvt_thread_mutex_lock( &mt->mt_mutex );
   
                                 /* clean up if the caller is giving up */                                  /* clean up if the caller is giving up */
Line 1814  typedef struct searchstate { Line 1848  typedef struct searchstate {
         BerVarray ss_ctxcsn;          BerVarray ss_ctxcsn;
         int *ss_sids;          int *ss_sids;
         int ss_numcsns;          int ss_numcsns;
         int ss_present;  #define SS_PRESENT      0x01
   #define SS_CHANGED      0x02
           int ss_flags;
 } searchstate;  } searchstate;
   
 static int  static int
Line 1831  syncprov_search_cleanup( Operation *op, Line 1867  syncprov_search_cleanup( Operation *op,
 typedef struct SyncOperationBuffer {  typedef struct SyncOperationBuffer {
         Operation               sob_op;          Operation               sob_op;
         Opheader                sob_hdr;          Opheader                sob_hdr;
           OpExtra                 sob_oe;
         AttributeName   sob_extra;      /* not always present */          AttributeName   sob_extra;      /* not always present */
         /* Further data allocated here */          /* Further data allocated here */
 } SyncOperationBuffer;  } SyncOperationBuffer;
Line 1859  syncprov_detach_op( Operation *op, synco Line 1896  syncprov_detach_op( Operation *op, synco
         sopbuf2 = ch_calloc( 1, size );          sopbuf2 = ch_calloc( 1, size );
         op2 = &sopbuf2->sob_op;          op2 = &sopbuf2->sob_op;
         op2->o_hdr = &sopbuf2->sob_hdr;          op2->o_hdr = &sopbuf2->sob_hdr;
           LDAP_SLIST_FIRST(&op2->o_extra) = &sopbuf2->sob_oe;
   
         /* Copy the fields we care about explicitly, leave the rest alone */          /* Copy the fields we care about explicitly, leave the rest alone */
         *op2->o_hdr = *op->o_hdr;          *op2->o_hdr = *op->o_hdr;
Line 1866  syncprov_detach_op( Operation *op, synco Line 1904  syncprov_detach_op( Operation *op, synco
         op2->o_time = op->o_time;          op2->o_time = op->o_time;
         op2->o_bd = on->on_info->oi_origdb;          op2->o_bd = on->on_info->oi_origdb;
         op2->o_request = op->o_request;          op2->o_request = op->o_request;
         op2->o_private = on;          LDAP_SLIST_FIRST(&op2->o_extra)->oe_key = on;
           LDAP_SLIST_NEXT(LDAP_SLIST_FIRST(&op2->o_extra), oe_next) = NULL;
   
         ptr = (char *) sopbuf2 + offsetof( SyncOperationBuffer, sob_extra );          ptr = (char *) sopbuf2 + offsetof( SyncOperationBuffer, sob_extra );
         if ( i ) {          if ( i ) {
Line 1917  syncprov_detach_op( Operation *op, synco Line 1956  syncprov_detach_op( Operation *op, synco
         op2->o_do_not_cache = 1;          op2->o_do_not_cache = 1;
   
         /* Add op2 to conn so abandon will find us */          /* Add op2 to conn so abandon will find us */
         ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex );  
         op->o_conn->c_n_ops_executing++;          op->o_conn->c_n_ops_executing++;
         op->o_conn->c_n_ops_completed--;          op->o_conn->c_n_ops_completed--;
         LDAP_STAILQ_INSERT_TAIL( &op->o_conn->c_ops, op2, o_next );          LDAP_STAILQ_INSERT_TAIL( &op->o_conn->c_ops, op2, o_next );
         so->s_flags |= PS_IS_DETACHED;          so->s_flags |= PS_IS_DETACHED;
         ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex );  
   
         /* Prevent anyone else from trying to send a result for this op */          /* Prevent anyone else from trying to send a result for this op */
         op->o_abandon = 1;          op->o_abandon = 1;
Line 2003  syncprov_search_response( Operation *op, Line 2040  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, ss->ss_ctxcsn,                  if ( ss->ss_flags & SS_CHANGED ) {
                         srs->sr_state.rid, srs->sr_state.sid );                          slap_compose_sync_cookie( op, &cookie, ss->ss_ctxcsn,
                                   srs->sr_state.rid, srs->sr_state.sid );
   
                 Debug( LDAP_DEBUG_SYNC, "syncprov_search_response: cookie=%s\n", cookie.bv_val, 0, 0 );                          Debug( LDAP_DEBUG_SYNC, "syncprov_search_response: cookie=%s\n", cookie.bv_val, 0, 0 );
                   }
   
                 /* Is this a regular refresh? */                  /* Is this a regular refresh?
                    * Note: refresh never gets here if there were no changes
                    */
                 if ( !ss->ss_so ) {                  if ( !ss->ss_so ) {
                         rs->sr_ctrls = op->o_tmpalloc( sizeof(LDAPControl *)*2,                          rs->sr_ctrls = op->o_tmpalloc( sizeof(LDAPControl *)*2,
                                 op->o_tmpmemctx );                                  op->o_tmpmemctx );
                         rs->sr_ctrls[1] = NULL;                          rs->sr_ctrls[1] = NULL;
                         rs->sr_err = syncprov_done_ctrl( op, rs, rs->sr_ctrls,                          rs->sr_err = syncprov_done_ctrl( op, rs, rs->sr_ctrls,
                                 0, 1, &cookie, ss->ss_present ?  LDAP_SYNC_REFRESH_PRESENTS :                                  0, 1, &cookie, ( ss->ss_flags & SS_PRESENT ) ?  LDAP_SYNC_REFRESH_PRESENTS :
                                         LDAP_SYNC_REFRESH_DELETES );                                          LDAP_SYNC_REFRESH_DELETES );
                         op->o_tmpfree( cookie.bv_val, op->o_tmpmemctx );                          op->o_tmpfree( cookie.bv_val, op->o_tmpmemctx );
                 } else {                  } else {
                 /* It's RefreshAndPersist, transition to Persist phase */                  /* It's RefreshAndPersist, transition to Persist phase */
                         syncprov_sendinfo( op, rs, ss->ss_present ?                          syncprov_sendinfo( op, rs, ( ss->ss_flags & SS_PRESENT ) ?
                                 LDAP_TAG_SYNC_REFRESH_PRESENT : LDAP_TAG_SYNC_REFRESH_DELETE,                                  LDAP_TAG_SYNC_REFRESH_PRESENT : LDAP_TAG_SYNC_REFRESH_DELETE,
                                 &cookie, 1, NULL, 0 );                                  ( ss->ss_flags & SS_CHANGED ) ? &cookie : NULL,
                         op->o_tmpfree( cookie.bv_val, op->o_tmpmemctx );                                  1, NULL, 0 );
                           if ( ss->ss_flags & SS_CHANGED )
                                   op->o_tmpfree( cookie.bv_val, op->o_tmpmemctx );
   
                         /* Detach this Op from frontend control */                          /* Detach this Op from frontend control */
                         ldap_pvt_thread_mutex_lock( &ss->ss_so->s_mutex );                          ldap_pvt_thread_mutex_lock( &ss->ss_so->s_mutex );
                           ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex );
   
                           /* But not if this connection was closed along the way */
                           if ( op->o_abandon ) {
                                   ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex );
                                   ldap_pvt_thread_mutex_unlock( &ss->ss_so->s_mutex );
                                   syncprov_free_syncop( ss->ss_so );
                                   return SLAPD_ABANDON;
   
                           } else {
                                   /* Turn off the refreshing flag */
                                   ss->ss_so->s_flags ^= PS_IS_REFRESHING;
   
                         /* Turn off the refreshing flag */                                  syncprov_detach_op( op, ss->ss_so, on );
                         ss->ss_so->s_flags ^= PS_IS_REFRESHING;  
   
                         syncprov_detach_op( op, ss->ss_so, on );                                  ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex );
   
                         /* If there are queued responses, fire them off */                                  /* If there are queued responses, fire them off */
                         if ( ss->ss_so->s_res )                                  if ( ss->ss_so->s_res )
                                 syncprov_qstart( ss->ss_so );                                          syncprov_qstart( ss->ss_so );
                           }
                         ldap_pvt_thread_mutex_unlock( &ss->ss_so->s_mutex );                          ldap_pvt_thread_mutex_unlock( &ss->ss_so->s_mutex );
   
                         return LDAP_SUCCESS;                          return LDAP_SUCCESS;
Line 2050  syncprov_op_search( Operation *op, SlapR Line 2105  syncprov_op_search( Operation *op, SlapR
         slap_overinst           *on = (slap_overinst *)op->o_bd->bd_info;          slap_overinst           *on = (slap_overinst *)op->o_bd->bd_info;
         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;          int gotstate = 0, changed = 0, do_present = 0;
         syncops *sop = NULL;          syncops *sop = NULL;
         searchstate *ss;          searchstate *ss;
         sync_control *srs;          sync_control *srs;
Line 2065  syncprov_op_search( Operation *op, SlapR Line 2120  syncprov_op_search( Operation *op, SlapR
                 return rs->sr_err;                  return rs->sr_err;
         }          }
   
         do_present = si->si_nopres ? 0 : 1;  
   
         srs = op->o_controls[slap_cids.sc_LDAPsync];          srs = op->o_controls[slap_cids.sc_LDAPsync];
         op->o_managedsait = SLAP_CONTROL_NONCRITICAL;          op->o_managedsait = SLAP_CONTROL_NONCRITICAL;
   
Line 2134  syncprov_op_search( Operation *op, SlapR Line 2187  syncprov_op_search( Operation *op, SlapR
                 if ( !numcsns )                  if ( !numcsns )
                         goto no_change;                          goto no_change;
   
                   if ( !si->si_nopres )
                           do_present = SS_PRESENT;
   
                 /* If there are SIDs we don't recognize in the cookie, drop them */                  /* If there are SIDs we don't recognize in the cookie, drop them */
                 for (i=0; i<srs->sr_state.numcsns; ) {                  for (i=0; i<srs->sr_state.numcsns; ) {
                         for (j=0; j<numcsns; j++) {                          for (j=0; j<numcsns; j++) {
Line 2164  syncprov_op_search( Operation *op, SlapR Line 2220  syncprov_op_search( Operation *op, SlapR
   
                 /* If nothing has changed, shortcut it */                  /* If nothing has changed, shortcut it */
                 if ( srs->sr_state.numcsns == numcsns ) {                  if ( srs->sr_state.numcsns == numcsns ) {
                         int i, j, changed = 0;                          int i, j;
                         for ( i=0; i<srs->sr_state.numcsns; i++ ) {                          for ( i=0; i<srs->sr_state.numcsns; i++ ) {
                                 for ( j=0; j<numcsns; j++ ) {                                  for ( j=0; j<numcsns; j++ ) {
                                         if ( srs->sr_state.sids[i] != sids[j] )                                          if ( srs->sr_state.sids[i] != sids[j] )
                                                 continue;                                                  continue;
                                         if ( !bvmatch( &srs->sr_state.ctxcsn[i], &ctxcsn[j] ))                                          if ( !bvmatch( &srs->sr_state.ctxcsn[i], &ctxcsn[j] ))
                                                 changed = 1;                                                  changed = SS_CHANGED;
                                         break;                                          break;
                                 }                                  }
                                 if ( changed )                                  if ( changed )
                                         break;                                          break;
                         }                          }
                         if ( !changed ) {                          if ( !changed ) {
 no_change:              nochange = 1;                                  do_present = 0;
                                 if ( !(op->o_sync_mode & SLAP_SYNC_PERSIST) ) {  no_change:              if ( !(op->o_sync_mode & SLAP_SYNC_PERSIST) ) {
                                         LDAPControl     *ctrls[2];                                          LDAPControl     *ctrls[2];
   
                                         ctrls[0] = NULL;                                          ctrls[0] = NULL;
Line 2234  no_change:  nochange = 1; Line 2290  no_change:  nochange = 1;
                                 return rs->sr_err;                                  return rs->sr_err;
                         }                          }
                 }                  }
           } else {
                   /* No consumer state, assume something has changed */
                   changed = SS_CHANGED;
         }          }
   
 shortcut:  shortcut:
Line 2245  shortcut: Line 2304  shortcut:
         }          }
   
         /* If something changed, find the changes */          /* If something changed, find the changes */
         if ( gotstate && !nochange ) {          if ( gotstate && changed ) {
                 Filter *fand, *fava;                  Filter *fand, *fava;
   
                 fand = op->o_tmpalloc( sizeof(Filter), op->o_tmpmemctx );                  fand = op->o_tmpalloc( sizeof(Filter), op->o_tmpmemctx );
Line 2272  shortcut: Line 2331  shortcut:
         ss = (searchstate *)(cb+1);          ss = (searchstate *)(cb+1);
         ss->ss_on = on;          ss->ss_on = on;
         ss->ss_so = sop;          ss->ss_so = sop;
         ss->ss_present = do_present;          ss->ss_flags = do_present | changed;
         ss->ss_ctxcsn = ctxcsn;          ss->ss_ctxcsn = ctxcsn;
         ss->ss_numcsns = numcsns;          ss->ss_numcsns = numcsns;
         ss->ss_sids = sids;          ss->ss_sids = sids;
Line 2286  shortcut: Line 2345  shortcut:
          * the refresh phase, just invoke the response callback to transition           * the refresh phase, just invoke the response callback to transition
          * us into persist phase           * us into persist phase
          */           */
         if ( nochange ) {          if ( !changed ) {
                 rs->sr_err = LDAP_SUCCESS;                  rs->sr_err = LDAP_SUCCESS;
                 rs->sr_nentries = 0;                  rs->sr_nentries = 0;
                 send_ldap_result( op, rs );                  send_ldap_result( op, rs );
Line 2303  syncprov_operational( Line 2362  syncprov_operational(
         slap_overinst           *on = (slap_overinst *)op->o_bd->bd_info;          slap_overinst           *on = (slap_overinst *)op->o_bd->bd_info;
         syncprov_info_t         *si = (syncprov_info_t *)on->on_bi.bi_private;          syncprov_info_t         *si = (syncprov_info_t *)on->on_bi.bi_private;
   
           /* This prevents generating unnecessarily; frontend will strip
            * any statically stored copy.
            */
           if ( op->o_sync != SLAP_CONTROL_NONE )
                   return SLAP_CB_CONTINUE;
   
         if ( rs->sr_entry &&          if ( rs->sr_entry &&
                 dn_match( &rs->sr_entry->e_nname, op->o_bd->be_nsuffix )) {                  dn_match( &rs->sr_entry->e_nname, op->o_bd->be_nsuffix )) {
   
Line 2400  sp_cf_gen(ConfigArgs *c) Line 2465  sp_cf_gen(ConfigArgs *c)
                 case SP_CHKPT:                  case SP_CHKPT:
                         if ( si->si_chkops || si->si_chktime ) {                          if ( si->si_chkops || si->si_chktime ) {
                                 struct berval bv;                                  struct berval bv;
                                 bv.bv_len = sprintf( c->cr_msg, "%d %d",                                  bv.bv_len = snprintf( c->cr_msg, sizeof( c->cr_msg ),
                                         si->si_chkops, si->si_chktime );                                          "%d %d", si->si_chkops, si->si_chktime );
                                 bv.bv_val = c->cr_msg;                                  if ( bv.bv_len < 0 || bv.bv_len >= sizeof( c->cr_msg ) ) {
                                 value_add_one( &c->rvalue_vals, &bv );                                          rc = 1;
                                   } else {
                                           bv.bv_val = c->cr_msg;
                                           value_add_one( &c->rvalue_vals, &bv );
                                   }
                         } else {                          } else {
                                 rc = 1;                                  rc = 1;
                         }                          }
Line 2818  static int syncprov_parseCtrl ( Line 2887  static int syncprov_parseCtrl (
         sr->sr_rhint = rhint;          sr->sr_rhint = rhint;
         if (!BER_BVISNULL(&cookie)) {          if (!BER_BVISNULL(&cookie)) {
                 ber_dupbv_x( &sr->sr_state.octet_str, &cookie, op->o_tmpmemctx );                  ber_dupbv_x( &sr->sr_state.octet_str, &cookie, op->o_tmpmemctx );
                   /* If parse fails, pretend no cookie was sent */
                 if ( slap_parse_sync_cookie( &sr->sr_state, op->o_tmpmemctx ) ||                  if ( slap_parse_sync_cookie( &sr->sr_state, op->o_tmpmemctx ) ||
                         sr->sr_state.rid == -1 ) {                          sr->sr_state.rid == -1 ) {
                         rs->sr_text = "Sync control : cookie parsing error";                          if ( sr->sr_state.ctxcsn ) {
                         return LDAP_PROTOCOL_ERROR;                                  ber_bvarray_free_x( sr->sr_state.ctxcsn, op->o_tmpmemctx );
                                   sr->sr_state.ctxcsn = NULL;
                           }
                           sr->sr_state.numcsns = 0;
                 }                  }
         }          }
   

Removed from v.1.147.2.11  
changed lines
  Added in v.1.224


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