Diff for /servers/slapd/back-bdb/modrdn.c between versions 1.110 and 1.110.2.11

version 1.110, 2003/05/24 22:53:08 version 1.110.2.11, 2004/02/23 22:08:06
Line 1 Line 1
 /* modrdn.c - bdb backend modrdn routine */  /* modrdn.c - bdb backend modrdn routine */
 /* $OpenLDAP: pkg/ldap/servers/slapd/back-bdb/modrdn.c,v 1.109 2003/05/23 23:54:03 hyc Exp $ */  /* $OpenLDAP: pkg/ldap/servers/slapd/back-bdb/modrdn.c,v 1.110.2.10 2004/01/01 18:16:36 kurt Exp $ */
 /*  /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.   *
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file   * Copyright 2000-2004 The OpenLDAP Foundation.
    * All rights reserved.
    *
    * Redistribution and use in source and binary forms, with or without
    * modification, are permitted only as authorized by the OpenLDAP
    * Public License.
    *
    * A copy of this license is available in the file LICENSE in the
    * top-level directory of the distribution or, alternatively, at
    * <http://www.OpenLDAP.org/license.html>.
  */   */
   
 #include "portable.h"  #include "portable.h"
Line 49  bdb_modrdn( Operation *op, SlapReply *rs Line 58  bdb_modrdn( Operation *op, SlapReply *rs
         u_int32_t       locker = 0;          u_int32_t       locker = 0;
         DB_LOCK         lock, plock, nplock;          DB_LOCK         lock, plock, nplock;
   
         int             noop = 0;          int             num_retries = 0;
   
 #if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)          LDAPControl *ctrls[SLAP_MAX_RESPONSE_CONTROLS];
         Operation *ps_list;          int num_ctrls = 0;
   
           Operation *ps_list;
         struct psid_entry *pm_list, *pm_prev;          struct psid_entry *pm_list, *pm_prev;
 #endif          int     rc;
           EntryInfo       *suffix_ei;
           Entry           *ctxcsn_e;
           int                     ctxcsn_added = 0;
   
           int parent_is_glue = 0;
           int parent_is_leaf = 0;
   
 #ifdef NEW_LOGGING  #ifdef NEW_LOGGING
         LDAP_LOG ( OPERATION, ENTRY, "==>bdb_modrdn(%s,%s,%s)\n",           LDAP_LOG ( OPERATION, ENTRY, "==>bdb_modrdn(%s,%s,%s)\n", 
Line 85  retry: /* transaction retry */ Line 102  retry: /* transaction retry */
 #else  #else
                 Debug( LDAP_DEBUG_TRACE, "==>bdb_modrdn: retrying...\n", 0, 0, 0 );                  Debug( LDAP_DEBUG_TRACE, "==>bdb_modrdn: retrying...\n", 0, 0, 0 );
 #endif  #endif
                   pm_list = LDAP_LIST_FIRST(&op->o_pm_list);
 #if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)                  while ( pm_list != NULL ) {
                 pm_list = LDAP_LIST_FIRST(&op->o_pm_list);                          LDAP_LIST_REMOVE ( pm_list, ps_link );
                 while ( pm_list != NULL ) {  
                         LDAP_LIST_REMOVE ( pm_list, ps_link );  
                         pm_prev = pm_list;                          pm_prev = pm_list;
                         pm_list = LDAP_LIST_NEXT ( pm_list, ps_link );                          pm_list = LDAP_LIST_NEXT ( pm_list, ps_link );
                         ch_free( pm_prev );                          ch_free( pm_prev );
                 }                  }
 #endif  
   
                 rs->sr_err = TXN_ABORT( ltid );                  rs->sr_err = TXN_ABORT( ltid );
                 ltid = NULL;                  ltid = NULL;
Line 105  retry: /* transaction retry */ Line 119  retry: /* transaction retry */
                         rs->sr_text = "internal error";                          rs->sr_text = "internal error";
                         goto return_results;                          goto return_results;
                 }                  }
                   parent_is_glue = 0;
                   parent_is_leaf = 0;
                 ldap_pvt_thread_yield();                  ldap_pvt_thread_yield();
                   bdb_trans_backoff( ++num_retries );
         }          }
   
         /* begin transaction */          /* begin transaction */
Line 157  retry: /* transaction retry */ Line 174  retry: /* transaction retry */
         }          }
   
         e = ei->bei_e;          e = ei->bei_e;
         if ( rs->sr_err == DB_NOTFOUND ) {          /* FIXME: dn2entry() should return non-glue entry */
           if (( rs->sr_err == DB_NOTFOUND ) || ( !manageDSAit && e && is_entry_glue( e ))) {
                 if( e != NULL ) {                  if( e != NULL ) {
                         rs->sr_matched = ch_strdup( e->e_dn );                          rs->sr_matched = ch_strdup( e->e_dn );
                         rs->sr_ref = is_entry_referral( e )                          rs->sr_ref = is_entry_referral( e )
Line 167  retry: /* transaction retry */ Line 185  retry: /* transaction retry */
                         e = NULL;                          e = NULL;
   
                 } else {                  } else {
                         rs->sr_ref = referral_rewrite( default_referral,                          BerVarray deref = NULL;
                                 NULL, &op->o_req_dn, LDAP_SCOPE_DEFAULT );                          if ( !LDAP_STAILQ_EMPTY( &op->o_bd->be_syncinfo )) {
                                   syncinfo_t *si;
                                   LDAP_STAILQ_FOREACH( si, &op->o_bd->be_syncinfo, si_next ) {
                                           struct berval tmpbv;
                                           ber_dupbv( &tmpbv, &si->si_provideruri_bv[0] );
                                           ber_bvarray_add( &deref, &tmpbv );
                   }
                           } else {
                                   deref = default_referral;
                           }
                           rs->sr_ref = referral_rewrite( deref, NULL, &op->o_req_dn,
                                   LDAP_SCOPE_DEFAULT );
                 }                  }
   
                 rs->sr_err = LDAP_REFERRAL;                  rs->sr_err = LDAP_REFERRAL;
Line 182  retry: /* transaction retry */ Line 211  retry: /* transaction retry */
                 goto done;                  goto done;
         }          }
   
           if ( get_assert( op ) &&
                   ( test_filter( op, e, get_assertion( op )) != LDAP_COMPARE_TRUE ))
           {
                   rs->sr_err = LDAP_ASSERTION_FAILED;
                   goto return_results;
           }
   
         /* check write on old entry */          /* check write on old entry */
         rs->sr_err = access_allowed( op, e, entry, NULL, ACL_WRITE, NULL );          rs->sr_err = access_allowed( op, e, entry, NULL, ACL_WRITE, NULL );
   
         if ( ! rs->sr_err ) {          if ( ! rs->sr_err ) {
                 switch( opinfo.boi_err ) {                  switch( opinfo.boi_err ) {
                 case DB_LOCK_DEADLOCK:                  case DB_LOCK_DEADLOCK:
Line 651  retry: /* transaction retry */ Line 686  retry: /* transaction retry */
         }          }
   
         /* Build target dn and make sure target entry doesn't exist already. */          /* Build target dn and make sure target entry doesn't exist already. */
         if (!new_dn.bv_val) build_new_dn( &new_dn, new_parent_dn, &op->oq_modrdn.rs_newrdn );           if (!new_dn.bv_val) build_new_dn( &new_dn, new_parent_dn, &op->oq_modrdn.rs_newrdn, NULL ); 
   
         if (!new_ndn.bv_val) {          if (!new_ndn.bv_val) {
                 struct berval bv = {0, NULL};                  struct berval bv = {0, NULL};
Line 667  retry: /* transaction retry */ Line 702  retry: /* transaction retry */
                 new_ndn.bv_val, 0, 0 );                  new_ndn.bv_val, 0, 0 );
 #endif  #endif
   
   
         /* Shortcut the search */          /* Shortcut the search */
         nei = neip ? neip : eip;          nei = neip ? neip : eip;
         rs->sr_err = bdb_cache_find_ndn ( op, ltid, &new_ndn, &nei, locker );          rs->sr_err = bdb_cache_find_ndn ( op, ltid, &new_ndn, &nei );
         if ( nei ) bdb_cache_entryinfo_unlock( nei );          if ( nei ) bdb_cache_entryinfo_unlock( nei );
         switch( rs->sr_err ) {          switch( rs->sr_err ) {
         case DB_LOCK_DEADLOCK:          case DB_LOCK_DEADLOCK:
Line 751  retry: /* transaction retry */ Line 787  retry: /* transaction retry */
                 }                  }
         }          }
   
           if( op->o_preread ) {
                   if( slap_read_controls( op, rs, e,
                           &slap_pre_read_bv, &ctrls[num_ctrls] ) )
                   {
   #ifdef NEW_LOGGING                                   
                           LDAP_LOG ( OPERATION, DETAIL1,
                                   "<=- bdb_modrdn: post-read failed!\n", 0, 0, 0 );
   #else
                           Debug( LDAP_DEBUG_TRACE,        
                                   "<=- bdb_modrdn: post-read failed!\n", 0, 0, 0 );
   #endif
                           goto return_results;
                   }                   
                   ctrls[++num_ctrls] = NULL;
                   op->o_preread = 0;  /* prevent redo on retry */
           }
   
         /* nested transaction */          /* nested transaction */
         rs->sr_err = TXN_BEGIN( bdb->bi_dbenv, ltid, &lt2,           rs->sr_err = TXN_BEGIN( bdb->bi_dbenv, ltid, &lt2, 
                 bdb->bi_db_opflags );                  bdb->bi_db_opflags );
Line 832  retry: /* transaction retry */ Line 885  retry: /* transaction retry */
                 goto return_results;                  goto return_results;
         }          }
   
 #if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)          if ( rs->sr_err == LDAP_SUCCESS && !op->o_noop && !op->o_no_psearch ) {
         if ( rs->sr_err == LDAP_SUCCESS && !op->o_noop ) {                  ldap_pvt_thread_rdwr_rlock( &bdb->bi_pslist_rwlock );
                 LDAP_LIST_FOREACH ( ps_list, &bdb->bi_psearch_list, o_ps_link ) {                  LDAP_LIST_FOREACH ( ps_list, &bdb->bi_psearch_list, o_ps_link ) {
                         bdb_psearch( op, rs, ps_list, e, LDAP_PSEARCH_BY_PREMODIFY );                          bdb_psearch( op, rs, ps_list, e, LDAP_PSEARCH_BY_PREMODIFY );
                 }                  }
                   ldap_pvt_thread_rdwr_runlock( &bdb->bi_pslist_rwlock );
         }          }
 #endif  
   
         /* modify entry */          /* modify entry */
         rs->sr_err = bdb_modify_internal( op, lt2, &mod[0], e,          rs->sr_err = bdb_modify_internal( op, lt2, &mod[0], e,
Line 864  retry: /* transaction retry */ Line 917  retry: /* transaction retry */
                 }                  }
                 goto return_results;                  goto return_results;
         }          }
           
           if( op->o_postread ) {
                   if( slap_read_controls( op, rs, e,
                           &slap_post_read_bv, &ctrls[num_ctrls] ) )
                   {
   #ifdef NEW_LOGGING                                   
                           LDAP_LOG ( OPERATION, DETAIL1,
                                   "<=- bdb_modrdn: post-read failed!\n", 0, 0, 0 );
   #else
                           Debug( LDAP_DEBUG_TRACE,        
                                   "<=- bdb_modrdn: post-read failed!\n", 0, 0, 0 );
   #endif
                           goto return_results;
                   }                   
                   ctrls[++num_ctrls] = NULL;
                   op->o_postread = 0;  /* prevent redo on retry */
                   /* FIXME: should read entry on the last retry */
           }
   
         /* id2entry index */          /* id2entry index */
         rs->sr_err = bdb_id2entry_update( op->o_bd, lt2, e );          rs->sr_err = bdb_id2entry_update( op->o_bd, lt2, e );
         if ( rs->sr_err != 0 ) {          if ( rs->sr_err != 0 ) {
Line 886  retry: /* transaction retry */ Line 957  retry: /* transaction retry */
                 rs->sr_text = "entry update failed";                  rs->sr_text = "entry update failed";
                 goto return_results;                  goto return_results;
         }          }
   
           bdb_cache_find_id( op, lt2, eip->bei_id, &eip, 0, locker, &plock );
       if ( eip ) p = eip->bei_e;
       if ( p_ndn.bv_len != 0 ) {
           parent_is_glue = is_entry_glue(p);
           rs->sr_err = bdb_cache_children( op, lt2, p );
           if ( rs->sr_err != DB_NOTFOUND ) {
               switch( rs->sr_err ) {
               case DB_LOCK_DEADLOCK:
               case DB_LOCK_NOTGRANTED:
                   goto retry;
               case 0:
                   break;
               default:
   #ifdef NEW_LOGGING
                   LDAP_LOG ( OPERATION, ERR,
                       "<=- bdb_modrdn: has_children failed %s (%d)\n",
                       db_strerror(rs->sr_err), rs->sr_err, 0 );
   #else
                   Debug(LDAP_DEBUG_ARGS,
                       "<=- bdb_modrdn: has_children failed: %s (%d)\n",
                       db_strerror(rs->sr_err), rs->sr_err, 0 );
   #endif
                   rs->sr_err = LDAP_OTHER;
                   rs->sr_text = "internal error";
                   goto return_results;
               }
               parent_is_leaf = 1;
           }
           bdb_unlocked_cache_return_entry_r(&bdb->bi_cache, p);
           p = NULL;
       }
   
         if ( TXN_COMMIT( lt2, 0 ) != 0 ) {          if ( TXN_COMMIT( lt2, 0 ) != 0 ) {
                 rs->sr_err = LDAP_OTHER;                  rs->sr_err = LDAP_OTHER;
                 rs->sr_text = "txn_commit(2) failed";                  rs->sr_text = "txn_commit(2) failed";
                 goto return_results;                  goto return_results;
         }          }
   
           if ( LDAP_STAILQ_EMPTY( &op->o_bd->be_syncinfo )) {
                   rc = bdb_csn_commit( op, rs, ltid, ei, &suffix_ei,
                           &ctxcsn_e, &ctxcsn_added, locker );
                   switch ( rc ) {
                   case BDB_CSN_ABORT :
                           goto return_results;
                   case BDB_CSN_RETRY :
                           goto retry;
                   }
           }
   
         if( op->o_noop ) {          if( op->o_noop ) {
                 if(( rs->sr_err=TXN_ABORT( ltid )) != 0 ) {                  if(( rs->sr_err=TXN_ABORT( ltid )) != 0 ) {
                         rs->sr_text = "txn_abort (no-op) failed";                          rs->sr_text = "txn_abort (no-op) failed";
                 } else {                  } else {
                         noop = 1;  
                         rs->sr_err = LDAP_SUCCESS;                          rs->sr_err = LDAP_SUCCESS;
                           goto return_results;
                 }                  }
   
         } else {          } else {
                 char gid[DB_XIDDATASIZE];                  bdb_cache_modrdn( save, &op->orr_nnewrdn, e, neip,
                           bdb->bi_dbenv, locker, &lock );
   
                 snprintf( gid, sizeof( gid ), "%s-%08lx-%08lx",                  if ( LDAP_STAILQ_EMPTY( &op->o_bd->be_syncinfo )) {
                         bdb_uuid.bv_val, (long) op->o_connid, (long) op->o_opid );                          if ( ctxcsn_added ) {
                                   bdb_cache_add( bdb, suffix_ei, ctxcsn_e,
                                           (struct berval *)&slap_ldapsync_cn_bv, locker );
                           }
                   }
   
                 if(( rs->sr_err=TXN_PREPARE( ltid, gid )) != 0 ) {                  if ( rs->sr_err == LDAP_SUCCESS ) {
                         rs->sr_text = "txn_prepare failed";                          /* Loop through in-scope entries for each psearch spec */
                 } else {                          ldap_pvt_thread_rdwr_rlock( &bdb->bi_pslist_rwlock );
                         bdb_cache_modrdn( save, &op->orr_nnewrdn, e, neip,                          LDAP_LIST_FOREACH ( ps_list, &bdb->bi_psearch_list, o_ps_link ) {
                                 bdb->bi_dbenv, locker, &lock );                                  bdb_psearch( op, rs, ps_list, e, LDAP_PSEARCH_BY_MODIFY );
                         if(( rs->sr_err=TXN_COMMIT( ltid, 0 )) != 0 ) {                          }
                                 rs->sr_text = "txn_commit failed";                          ldap_pvt_thread_rdwr_runlock( &bdb->bi_pslist_rwlock );
                         } else {                          pm_list = LDAP_LIST_FIRST(&op->o_pm_list);
                                 rs->sr_err = LDAP_SUCCESS;                          while ( pm_list != NULL ) {
                                   bdb_psearch(op, rs, pm_list->ps_op,
                                                           e, LDAP_PSEARCH_BY_SCOPEOUT);
                                   pm_prev = pm_list;
                                   LDAP_LIST_REMOVE ( pm_list, ps_link );
                                   pm_list = LDAP_LIST_NEXT ( pm_list, ps_link );
                                   ch_free( pm_prev );
                         }                          }
                 }                  }
   
                   if(( rs->sr_err=TXN_COMMIT( ltid, 0 )) != 0 ) {
                           rs->sr_text = "txn_commit failed";
                   } else {
                           rs->sr_err = LDAP_SUCCESS;
                   }
         }          }
     
         ltid = NULL;          ltid = NULL;
         op->o_private = NULL;          op->o_private = NULL;
     
         if( rs->sr_err == LDAP_SUCCESS ) {          if( rs->sr_err != LDAP_SUCCESS ) {
 #ifdef NEW_LOGGING  
                 LDAP_LOG ( OPERATION, RESULTS,   
                         "bdb_modrdn: rdn modified%s id=%08lx dn=\"%s\"\n",   
                         op->o_noop ? " (no-op)" : "", e->e_id, e->e_dn );  
 #else  
                 Debug(LDAP_DEBUG_TRACE,  
                         "bdb_modrdn: rdn modified%s id=%08lx dn=\"%s\"\n",  
                         op->o_noop ? " (no-op)" : "", e->e_id, e->e_dn );  
 #endif  
                 rs->sr_text = NULL;  
         } else {  
 #ifdef NEW_LOGGING  #ifdef NEW_LOGGING
                 LDAP_LOG ( OPERATION, RESULTS, "bdb_modrdn: %s : %s (%d)\n",                   LDAP_LOG ( OPERATION, RESULTS, "bdb_modrdn: %s : %s (%d)\n", 
                         rs->sr_text, db_strerror(rs->sr_err), rs->sr_err );                          rs->sr_text, db_strerror(rs->sr_err), rs->sr_err );
Line 942  retry: /* transaction retry */ Line 1063  retry: /* transaction retry */
                         rs->sr_text, db_strerror(rs->sr_err), rs->sr_err );                          rs->sr_text, db_strerror(rs->sr_err), rs->sr_err );
 #endif  #endif
                 rs->sr_err = LDAP_OTHER;                  rs->sr_err = LDAP_OTHER;
   
                   goto return_results;
         }          }
   
   #ifdef NEW_LOGGING
           LDAP_LOG ( OPERATION, RESULTS, 
                   "bdb_modrdn: rdn modified%s id=%08lx dn=\"%s\"\n", 
                   op->o_noop ? " (no-op)" : "",
                   e->e_id, e->e_dn );
   #else
           Debug(LDAP_DEBUG_TRACE,
                   "bdb_modrdn: rdn modified%s id=%08lx dn=\"%s\"\n",
                   op->o_noop ? " (no-op)" : "",
                   e->e_id, e->e_dn );
   #endif
           rs->sr_text = NULL;
           if( num_ctrls ) rs->sr_ctrls = ctrls;
   
 return_results:  return_results:
         send_ldap_result( op, rs );          send_ldap_result( op, rs );
   
 #if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)  
         if ( rs->sr_err == LDAP_SUCCESS && !op->o_noop ) {  
                 /* Loop through in-scope entries for each psearch spec */  
                 LDAP_LIST_FOREACH ( ps_list, &bdb->bi_psearch_list, o_ps_link ) {  
                         bdb_psearch( op, rs, ps_list, e, LDAP_PSEARCH_BY_MODIFY );  
                 }  
                 pm_list = LDAP_LIST_FIRST(&op->o_pm_list);  
                 while ( pm_list != NULL ) {  
                         bdb_psearch(op, rs, pm_list->ps_op,  
                                                 e, LDAP_PSEARCH_BY_SCOPEOUT);  
                         pm_prev = pm_list;  
                         LDAP_LIST_REMOVE ( pm_list, ps_link );  
                         pm_list = LDAP_LIST_NEXT ( pm_list, ps_link );  
                         ch_free( pm_prev );  
                 }  
         }  
 #endif  
   
         if( rs->sr_err == LDAP_SUCCESS && bdb->bi_txn_cp ) {          if( rs->sr_err == LDAP_SUCCESS && bdb->bi_txn_cp ) {
                 ldap_pvt_thread_yield();                  ldap_pvt_thread_yield();
                 TXN_CHECKPOINT( bdb->bi_dbenv,                  TXN_CHECKPOINT( bdb->bi_dbenv,
                         bdb->bi_txn_cp_kbyte, bdb->bi_txn_cp_min, 0 );                          bdb->bi_txn_cp_kbyte, bdb->bi_txn_cp_min, 0 );
         }          }
           
           if ( rs->sr_err == LDAP_SUCCESS && parent_is_glue && parent_is_leaf ) {
                   op->o_delete_glue_parent = 1;
           }
   
 done:  done:
         if( new_dn.bv_val != NULL ) free( new_dn.bv_val );          if( new_dn.bv_val != NULL ) free( new_dn.bv_val );
Line 986  done: Line 1109  done:
                 Modifications *tmp;                  Modifications *tmp;
                 for (; mod; mod=tmp ) {                  for (; mod; mod=tmp ) {
                         tmp = mod->sml_next;                          tmp = mod->sml_next;
                           /* slap_modrdn2mods does things one way,
                            * slap_mods_opattrs does it differently
                            */
                           if ( mod->sml_op != SLAP_MOD_SOFTADD &&
                                   mod->sml_op != LDAP_MOD_DELETE ) break;
                         if ( mod->sml_nvalues ) free( mod->sml_nvalues[0].bv_val );                          if ( mod->sml_nvalues ) free( mod->sml_nvalues[0].bv_val );
                         free( mod );                          free( mod );
                 }                  }
                   slap_mods_free( mod );
         }          }
   
         /* LDAP v3 Support */          /* LDAP v3 Support */
Line 1008  done: Line 1137  done:
         }          }
   
         if( ltid != NULL ) {          if( ltid != NULL ) {
 #if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)                  pm_list = LDAP_LIST_FIRST(&op->o_pm_list);
                 pm_list = LDAP_LIST_FIRST(&op->o_pm_list);                  while ( pm_list != NULL ) {
                 while ( pm_list != NULL ) {                          LDAP_LIST_REMOVE ( pm_list, ps_link );
                         LDAP_LIST_REMOVE ( pm_list, ps_link );  
                         pm_prev = pm_list;                          pm_prev = pm_list;
                         pm_list = LDAP_LIST_NEXT ( pm_list, ps_link );                          pm_list = LDAP_LIST_NEXT ( pm_list, ps_link );
                         ch_free( pm_prev );                          ch_free( pm_prev );
                 }                  }
 #endif  
                 TXN_ABORT( ltid );                  TXN_ABORT( ltid );
                 op->o_private = NULL;                  op->o_private = NULL;
         }          }
   
         return ( ( rs->sr_err == LDAP_SUCCESS ) ? noop : rs->sr_err );          return rs->sr_err;
 }  }

Removed from v.1.110  
changed lines
  Added in v.1.110.2.11


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