Diff for /servers/slapd/overlays/syncprov.c between versions 1.147.2.3 and 1.150

version 1.147.2.3, 2006/10/19 20:06:55 version 1.150, 2006/05/11 08:46:44
Line 1 Line 1
 /* $OpenLDAP: pkg/ldap/servers/slapd/overlays/syncprov.c,v 1.147.2.2 2006/08/17 23:50:32 kurt Exp $ */  /* $OpenLDAP: pkg/ldap/servers/slapd/overlays/syncprov.c,v 1.149 2006/05/02 03:08:59 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 65  typedef struct syncops { Line 65  typedef struct syncops {
 #define PS_IS_DETACHED          0x02  #define PS_IS_DETACHED          0x02
 #define PS_WROTE_BASE           0x04  #define PS_WROTE_BASE           0x04
 #define PS_FIND_BASE            0x08  #define PS_FIND_BASE            0x08
 #define PS_FIX_FILTER           0x10  
   
         int             s_inuse;        /* reference count */          int             s_inuse;        /* reference count */
         struct syncres *s_res;          struct syncres *s_res;
Line 774  syncprov_sendresp( Operation *op, opcook Line 773  syncprov_sendresp( Operation *op, opcook
                         rs.sr_flags = REP_ENTRY_MUSTRELEASE;                          rs.sr_flags = REP_ENTRY_MUSTRELEASE;
                 if ( opc->sreference ) {                  if ( opc->sreference ) {
                         rs.sr_ref = get_entry_referrals( op, rs.sr_entry );                          rs.sr_ref = get_entry_referrals( op, rs.sr_entry );
                         rs.sr_err = send_search_reference( op, &rs );                          send_search_reference( op, &rs );
                         ber_bvarray_free( rs.sr_ref );                          ber_bvarray_free( rs.sr_ref );
                         if ( !rs.sr_entry )                          if ( !rs.sr_entry )
                                 *e = NULL;                                  *e = NULL;
Line 786  syncprov_sendresp( Operation *op, opcook Line 785  syncprov_sendresp( Operation *op, opcook
                 if ( rs.sr_entry->e_private )                  if ( rs.sr_entry->e_private )
                         rs.sr_flags = REP_ENTRY_MUSTRELEASE;                          rs.sr_flags = REP_ENTRY_MUSTRELEASE;
                 rs.sr_attrs = op->ors_attrs;                  rs.sr_attrs = op->ors_attrs;
                 rs.sr_err = send_search_entry( op, &rs );                  send_search_entry( op, &rs );
                 if ( !rs.sr_entry )                  if ( !rs.sr_entry )
                         *e = NULL;                          *e = NULL;
                 break;                  break;
Line 798  syncprov_sendresp( Operation *op, opcook Line 797  syncprov_sendresp( Operation *op, opcook
                 if ( opc->sreference ) {                  if ( opc->sreference ) {
                         struct berval bv = BER_BVNULL;                          struct berval bv = BER_BVNULL;
                         rs.sr_ref = &bv;                          rs.sr_ref = &bv;
                         rs.sr_err = send_search_reference( op, &rs );                          send_search_reference( op, &rs );
                 } else {                  } else {
                         rs.sr_err = send_search_entry( op, &rs );                          send_search_entry( op, &rs );
                 }                  }
                 break;                  break;
         default:          default:
Line 878  syncprov_qtask( void *ctx, void *arg ) Line 877  syncprov_qtask( void *ctx, void *arg )
         OperationBuffer opbuf;          OperationBuffer opbuf;
         Operation *op;          Operation *op;
         BackendDB be;          BackendDB be;
         int rc;  
   
         op = (Operation *) &opbuf;          op = (Operation *) &opbuf;
         *op = *so->s_op;          *op = *so->s_op;
Line 899  syncprov_qtask( void *ctx, void *arg ) Line 897  syncprov_qtask( void *ctx, void *arg )
         op->o_private = NULL;          op->o_private = NULL;
         op->o_callback = NULL;          op->o_callback = NULL;
   
         rc = syncprov_qplay( op, on, so );          (void)syncprov_qplay( op, on, so );
   
         /* decrement use count... */          /* decrement use count... */
         syncprov_free_syncop( so );          syncprov_free_syncop( so );
   
         /* wait until we get explicitly scheduled again */          /* wait until we get explicitly scheduled again */
         ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex );          ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex );
         ldap_pvt_runqueue_stoptask( &slapd_rq, rtask );          ldap_pvt_runqueue_stoptask( &slapd_rq, so->s_qtask );
         if ( rc == 0 ) {          ldap_pvt_runqueue_resched( &slapd_rq, so->s_qtask, 1 );
                 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( &slapd_rq.rq_mutex );
   
 #if 0   /* FIXME: connection_close isn't exported from slapd.  
                  * should it be?  
                  */  
         if ( rc ) {  
                 ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex );  
                 if ( connection_state_closing( op->o_conn )) {  
                         connection_close( op->o_conn );  
                 }  
                 ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex );  
         }  
 #endif  
         return NULL;          return NULL;
 }  }
   
 /* Start the task to play back queued psearch responses */  
 static void  
 syncprov_qstart( syncops *so )  
 {  
         int wake=0;  
         ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex );  
         if ( !so->s_qtask ) {  
                 so->s_qtask = ldap_pvt_runqueue_insert( &slapd_rq, RUNQ_INTERVAL,  
                         syncprov_qtask, so, "syncprov_qtask",  
                         so->s_op->o_conn->c_peer_name.bv_val );  
                 ++so->s_inuse;  
                 wake = 1;  
         } else {  
                 if (!ldap_pvt_runqueue_isrunning( &slapd_rq, so->s_qtask ) &&  
                         !so->s_qtask->next_sched.tv_sec ) {  
                         so->s_qtask->interval.tv_sec = 0;  
                         ldap_pvt_runqueue_resched( &slapd_rq, so->s_qtask, 0 );  
                         so->s_qtask->interval.tv_sec = RUNQ_INTERVAL;  
                         ++so->s_inuse;  
                         wake = 1;  
                 }  
         }  
         ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex );  
         if ( wake )  
                 slap_wake_listener();  
 }  
   
 /* Queue a persistent search response */  /* Queue a persistent search response */
 static int  static int
 syncprov_qresp( opcookie *opc, syncops *so, int mode )  syncprov_qresp( opcookie *opc, syncops *so, int mode )
Line 994  syncprov_qresp( opcookie *opc, syncops * Line 949  syncprov_qresp( opcookie *opc, syncops *
                 so->s_flags |= PS_FIND_BASE;                  so->s_flags |= PS_FIND_BASE;
         }          }
         if ( so->s_flags & PS_IS_DETACHED ) {          if ( so->s_flags & PS_IS_DETACHED ) {
                 syncprov_qstart( so );                  int wake=0;
                   ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex );
                   if ( !so->s_qtask ) {
                           so->s_qtask = ldap_pvt_runqueue_insert( &slapd_rq, RUNQ_INTERVAL,
                                   syncprov_qtask, so, "syncprov_qtask",
                                   so->s_op->o_conn->c_peer_name.bv_val );
                           ++so->s_inuse;
                           wake = 1;
                   } else {
                           if (!ldap_pvt_runqueue_isrunning( &slapd_rq, so->s_qtask ) &&
                                   !so->s_qtask->next_sched.tv_sec ) {
                                   so->s_qtask->interval.tv_sec = 0;
                                   ldap_pvt_runqueue_resched( &slapd_rq, so->s_qtask, 0 );
                                   so->s_qtask->interval.tv_sec = RUNQ_INTERVAL;
                                   ++so->s_inuse;
                                   wake = 1;
                           }
                   }
                   ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex );
                   if ( wake )
                           slap_wake_listener();
         }          }
         ldap_pvt_thread_mutex_unlock( &so->s_mutex );          ldap_pvt_thread_mutex_unlock( &so->s_mutex );
         return LDAP_SUCCESS;          return LDAP_SUCCESS;
Line 1080  syncprov_matchops( Operation *op, opcook Line 1055  syncprov_matchops( Operation *op, opcook
         int rc;          int rc;
         struct berval newdn;          struct berval newdn;
         int freefdn = 0;          int freefdn = 0;
         BackendDB *b0 = op->o_bd, db;  
   
         fc.fdn = &op->o_req_ndn;          fc.fdn = &op->o_req_ndn;
         /* compute new DN */          /* compute new DN */
Line 1093  syncprov_matchops( Operation *op, opcook Line 1067  syncprov_matchops( Operation *op, opcook
                 freefdn = 1;                  freefdn = 1;
         }          }
         if ( op->o_tag != LDAP_REQ_ADD ) {          if ( op->o_tag != LDAP_REQ_ADD ) {
                 if ( !SLAP_ISOVERLAY( op->o_bd )) {  
                         db = *op->o_bd;  
                         op->o_bd = &db;  
                 }  
                 op->o_bd->bd_info = (BackendInfo *)on->on_info;                  op->o_bd->bd_info = (BackendInfo *)on->on_info;
                 rc = be_entry_get_rw( op, fc.fdn, NULL, NULL, 0, &e );                  rc = be_entry_get_rw( op, fc.fdn, NULL, NULL, 0, &e );
                 /* If we're sending responses now, make a copy and unlock the DB */                  /* If we're sending responses now, make a copy and unlock the DB */
Line 1106  syncprov_matchops( Operation *op, opcook Line 1076  syncprov_matchops( Operation *op, opcook
                         e = e2;                          e = e2;
                 }                  }
                 op->o_bd->bd_info = (BackendInfo *)on;                  op->o_bd->bd_info = (BackendInfo *)on;
                 if ( rc ) {                  if ( rc ) return;
                         op->o_bd = b0;  
                         return;  
                 }  
         } else {          } else {
                 e = op->ora_e;                  e = op->ora_e;
         }          }
Line 1207  syncprov_matchops( Operation *op, opcook Line 1174  syncprov_matchops( Operation *op, opcook
         if ( freefdn ) {          if ( freefdn ) {
                 op->o_tmpfree( fc.fdn->bv_val, op->o_tmpmemctx );                  op->o_tmpfree( fc.fdn->bv_val, op->o_tmpmemctx );
         }          }
         op->o_bd = b0;  
 }  }
   
 static int  static int
Line 1269  syncprov_checkpoint( Operation *op, Slap Line 1235  syncprov_checkpoint( Operation *op, Slap
         struct berval bv[2];          struct berval bv[2];
         slap_callback cb = {0};          slap_callback cb = {0};
   
         /* If ctxcsn is empty, delete it */          mod.sml_values = bv;
         if ( BER_BVISEMPTY( &si->si_ctxcsn )) {          bv[1].bv_val = NULL;
                 mod.sml_values = NULL;          bv[0] = si->si_ctxcsn;
         } else {  
                 mod.sml_values = bv;  
                 bv[1].bv_val = NULL;  
                 bv[0] = si->si_ctxcsn;  
         }  
         mod.sml_nvalues = NULL;          mod.sml_nvalues = NULL;
         mod.sml_desc = slap_schema.si_ad_contextCSN;          mod.sml_desc = slap_schema.si_ad_contextCSN;
         mod.sml_op = LDAP_MOD_REPLACE;          mod.sml_op = LDAP_MOD_REPLACE;
Line 1301  syncprov_checkpoint( Operation *op, Slap Line 1262  syncprov_checkpoint( Operation *op, Slap
 }  }
   
 static void  static void
 syncprov_add_slog( Operation *op )  syncprov_add_slog( Operation *op, struct berval *csn )
 {  {
         opcookie *opc = op->o_callback->sc_private;          opcookie *opc = op->o_callback->sc_private;
         slap_overinst *on = opc->son;          slap_overinst *on = opc->son;
Line 1313  syncprov_add_slog( Operation *op ) Line 1274  syncprov_add_slog( Operation *op )
         {          {
                 /* Allocate a record. UUIDs are not NUL-terminated. */                  /* Allocate a record. UUIDs are not NUL-terminated. */
                 se = ch_malloc( sizeof( slog_entry ) + opc->suuid.bv_len +                   se = ch_malloc( sizeof( slog_entry ) + opc->suuid.bv_len + 
                         op->o_csn.bv_len + 1 );                          csn->bv_len + 1 );
                 se->se_next = NULL;                  se->se_next = NULL;
                 se->se_tag = op->o_tag;                  se->se_tag = op->o_tag;
   
Line 1322  syncprov_add_slog( Operation *op ) Line 1283  syncprov_add_slog( Operation *op )
                 se->se_uuid.bv_len = opc->suuid.bv_len;                  se->se_uuid.bv_len = opc->suuid.bv_len;
   
                 se->se_csn.bv_val = se->se_uuid.bv_val + opc->suuid.bv_len;                  se->se_csn.bv_val = se->se_uuid.bv_val + opc->suuid.bv_len;
                 AC_MEMCPY( se->se_csn.bv_val, op->o_csn.bv_val, op->o_csn.bv_len );                  AC_MEMCPY( se->se_csn.bv_val, csn->bv_val, csn->bv_len );
                 se->se_csn.bv_val[op->o_csn.bv_len] = '\0';                  se->se_csn.bv_val[csn->bv_len] = '\0';
                 se->se_csn.bv_len = op->o_csn.bv_len;                  se->se_csn.bv_len = csn->bv_len;
   
                 ldap_pvt_thread_mutex_lock( &sl->sl_mutex );                  ldap_pvt_thread_mutex_lock( &sl->sl_mutex );
                 if ( sl->sl_head ) {                  if ( sl->sl_head ) {
Line 1396  syncprov_playlog( Operation *op, SlapRep Line 1357  syncprov_playlog( Operation *op, SlapRep
                         i++;                          i++;
                         AC_MEMCPY( cbuf, se->se_csn.bv_val, se->se_csn.bv_len );                          AC_MEMCPY( cbuf, se->se_csn.bv_val, se->se_csn.bv_len );
                         delcsn.bv_len = se->se_csn.bv_len;                          delcsn.bv_len = se->se_csn.bv_len;
                         delcsn.bv_val[delcsn.bv_len] = '\0';  
                 } else {                  } else {
                         nmods++;                          nmods++;
                         j = num - nmods;                          j = num - nmods;
Line 1508  syncprov_op_response( Operation *op, Sla Line 1468  syncprov_op_response( Operation *op, Sla
   
         if ( rs->sr_err == LDAP_SUCCESS )          if ( rs->sr_err == LDAP_SUCCESS )
         {          {
                 struct berval maxcsn = BER_BVNULL;                  struct berval maxcsn = BER_BVNULL, curcsn = BER_BVNULL;
                 char cbuf[LDAP_LUTIL_CSNSTR_BUFSIZE];                  char cbuf[LDAP_LUTIL_CSNSTR_BUFSIZE];
   
                 /* Update our context CSN */                  /* Update our context CSN */
                 cbuf[0] = '\0';                  cbuf[0] = '\0';
                 ldap_pvt_thread_mutex_lock( &si->si_csn_mutex );                  ldap_pvt_thread_mutex_lock( &si->si_csn_mutex );
                 slap_get_commit_csn( op, &maxcsn );                  slap_get_commit_csn( op, &maxcsn, &curcsn );
                 if ( !BER_BVISNULL( &maxcsn ) ) {                  if ( !BER_BVISNULL( &maxcsn ) ) {
                         strcpy( cbuf, maxcsn.bv_val );                          strcpy( cbuf, maxcsn.bv_val );
                         if ( ber_bvcmp( &maxcsn, &si->si_ctxcsn ) > 0 ) {                          if ( ber_bvcmp( &maxcsn, &si->si_ctxcsn ) > 0 ) {
Line 1575  syncprov_op_response( Operation *op, Sla Line 1535  syncprov_op_response( Operation *op, Sla
   
                 /* Add any log records */                  /* Add any log records */
                 if ( si->si_logs && op->o_tag != LDAP_REQ_ADD ) {                  if ( si->si_logs && op->o_tag != LDAP_REQ_ADD ) {
                         syncprov_add_slog( op );                          syncprov_add_slog( op, &curcsn );
                 }                  }
   
         }          }
Line 1810  syncprov_detach_op( Operation *op, synco Line 1770  syncprov_detach_op( Operation *op, synco
         op2->ors_filterstr.bv_val = ptr;          op2->ors_filterstr.bv_val = ptr;
         strcpy( ptr, so->s_filterstr.bv_val );          strcpy( ptr, so->s_filterstr.bv_val );
         op2->ors_filterstr.bv_len = so->s_filterstr.bv_len;          op2->ors_filterstr.bv_len = so->s_filterstr.bv_len;
           op2->ors_filter = filter_dup( op->ors_filter, NULL );
         /* Skip the AND/GE clause that we stuck on in front */  
         if ( so->s_flags & PS_FIX_FILTER ) {  
                 op2->ors_filter = op->ors_filter->f_and->f_next;  
                 so->s_flags ^= PS_FIX_FILTER;  
         } else {  
                 op2->ors_filter = op->ors_filter;  
         }  
         op2->ors_filter = filter_dup( op2->ors_filter, NULL );  
         so->s_op = op2;          so->s_op = op2;
   
         /* Copy any cached group ACLs individually */          /* Copy any cached group ACLs individually */
Line 1910  syncprov_search_response( Operation *op, Line 1862  syncprov_search_response( Operation *op,
                         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_present && rs->sr_nentries ) ?
                                 LDAP_TAG_SYNC_REFRESH_PRESENT : LDAP_TAG_SYNC_REFRESH_DELETE,                                  LDAP_TAG_SYNC_REFRESH_PRESENT : LDAP_TAG_SYNC_REFRESH_DELETE,
                                 &cookie, 1, NULL, 0 );                                  &cookie, 1, NULL, 0 );
                         op->o_tmpfree( cookie.bv_val, op->o_tmpmemctx );                          op->o_tmpfree( cookie.bv_val, op->o_tmpmemctx );
Line 1922  syncprov_search_response( Operation *op, Line 1874  syncprov_search_response( Operation *op,
                         ss->ss_so->s_flags ^= PS_IS_REFRESHING;                          ss->ss_so->s_flags ^= PS_IS_REFRESHING;
   
                         syncprov_detach_op( op, ss->ss_so, on );                          syncprov_detach_op( op, ss->ss_so, on );
   
                         /* If there are queued responses, fire them off */  
                         if ( ss->ss_so->s_res )  
                                 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 2033  syncprov_op_search( Operation *op, SlapR Line 1981  syncprov_op_search( Operation *op, SlapR
                 sl=si->si_logs;                  sl=si->si_logs;
                 if ( sl ) {                  if ( sl ) {
                         ldap_pvt_thread_mutex_lock( &sl->sl_mutex );                          ldap_pvt_thread_mutex_lock( &sl->sl_mutex );
                         /* Are there any log entries, and is the consumer state                          if ( ber_bvcmp( &srs->sr_state.ctxcsn, &sl->sl_mincsn ) >= 0 ) {
                          * present in the session log?  
                          */  
                         if ( sl->sl_num > 0 && ber_bvcmp( &srs->sr_state.ctxcsn, &sl->sl_mincsn ) >= 0 ) {  
                                 do_present = 0;                                  do_present = 0;
                                 /* mutex is unlocked in playlog */                                  /* mutex is unlocked in playlog */
                                 syncprov_playlog( op, rs, sl, srs, &ctxcsn );                                  syncprov_playlog( op, rs, sl, srs, &ctxcsn );
Line 2090  shortcut: Line 2035  shortcut:
                 fava->f_next = op->ors_filter;                  fava->f_next = op->ors_filter;
                 op->ors_filter = fand;                  op->ors_filter = fand;
                 filter2bv_x( op, op->ors_filter, &op->ors_filterstr );                  filter2bv_x( op, op->ors_filter, &op->ors_filterstr );
                 if ( sop )  
                         sop->s_flags |= PS_FIX_FILTER;  
         }          }
   
         /* Let our callback add needed info to returned entries */          /* Let our callback add needed info to returned entries */
Line 2149  syncprov_operational( Line 2092  syncprov_operational(
                         if ( !a ) {                          if ( !a ) {
                                 for ( ap = &rs->sr_operational_attrs; *ap; ap=&(*ap)->a_next );                                  for ( ap = &rs->sr_operational_attrs; *ap; ap=&(*ap)->a_next );
   
                                 a = attr_alloc( slap_schema.si_ad_contextCSN );                                  a = ch_malloc( sizeof(Attribute));
                                   a->a_desc = slap_schema.si_ad_contextCSN;
                                 a->a_vals = ch_malloc( 2 * sizeof(struct berval));                                  a->a_vals = ch_malloc( 2 * sizeof(struct berval));
                                 a->a_vals[1].bv_val = NULL;                                  a->a_vals[1].bv_val = NULL;
                                 a->a_nvals = a->a_vals;                                  a->a_nvals = a->a_vals;
                                   a->a_next = NULL;
                                   a->a_flags = 0;
                                 *ap = a;                                  *ap = a;
                         }                          }
   
Line 2371  syncprov_db_open( Line 2317  syncprov_db_open(
         int rc;          int rc;
         void *thrctx = NULL;          void *thrctx = NULL;
   
         if ( !SLAP_LASTMOD( be )) {  
                 Debug( LDAP_DEBUG_ANY,  
                         "syncprov_db_open: invalid config, lastmod must be enabled\n", 0, 0, 0 );  
                 return -1;  
         }  
   
         if ( slapMode & SLAP_TOOL_MODE ) {          if ( slapMode & SLAP_TOOL_MODE ) {
                 return 0;                  return 0;
         }          }
Line 2420  syncprov_db_open( Line 2360  syncprov_db_open(
                         ldap_pvt_thread_create( &tid, 0, syncprov_db_otask, op );                          ldap_pvt_thread_create( &tid, 0, syncprov_db_otask, op );
                         ldap_pvt_thread_join( tid, NULL );                          ldap_pvt_thread_join( tid, NULL );
                 }                  }
         }          } else if ( SLAP_SYNC_SHADOW( op->o_bd )) {
                   /* If we're also a consumer, and we didn't find the context entry,
         if ( BER_BVISEMPTY( &si->si_ctxcsn ) ) {  
                 if ( SLAP_SYNC_SHADOW( op->o_bd )) {  
                 /* If we're also a consumer, and we didn't get a contextCSN,  
                  * then don't generate anything, wait for our provider to send it                   * then don't generate anything, wait for our provider to send it
                  * to us.                   * to us.
                  */                   */
                         goto out;                  goto out;
                 }          }
   
           if ( BER_BVISEMPTY( &si->si_ctxcsn ) ) {
                 si->si_ctxcsn.bv_len = sizeof( si->si_ctxcsnbuf );                  si->si_ctxcsn.bv_len = sizeof( si->si_ctxcsnbuf );
                 slap_get_csn( op, &si->si_ctxcsn, 0 );                  slap_get_csn( op, &si->si_ctxcsn, 0 );
         }          }

Removed from v.1.147.2.3  
changed lines
  Added in v.1.150


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