mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-03-31 14:50:34 +08:00
redesign of back-bdb locking :
cache entry is locked by Berkeley DB lock primitives.
This commit is contained in:
parent
55e925abe6
commit
7341dc5db6
@ -23,7 +23,7 @@ bdb_add(
|
||||
struct bdb_info *bdb = (struct bdb_info *) be->be_private;
|
||||
struct berval pdn;
|
||||
Entry *p = NULL;
|
||||
int rc;
|
||||
int rc, ret;
|
||||
const char *text;
|
||||
char textbuf[SLAP_TEXT_BUFLEN];
|
||||
size_t textlen = sizeof textbuf;
|
||||
@ -33,6 +33,8 @@ bdb_add(
|
||||
#ifdef BDB_SUBENTRIES
|
||||
int subentry;
|
||||
#endif
|
||||
u_int32_t locker;
|
||||
DB_LOCK lock;
|
||||
#if 0
|
||||
u_int32_t lockid;
|
||||
DB_LOCK lock;
|
||||
@ -108,6 +110,8 @@ retry: /* transaction retry */
|
||||
text = "internal error";
|
||||
goto return_results;
|
||||
}
|
||||
|
||||
locker = TXN_ID ( ltid );
|
||||
#if 0
|
||||
lockid = TXN_ID( ltid );
|
||||
#endif
|
||||
@ -142,7 +146,7 @@ retry: /* transaction retry */
|
||||
#endif
|
||||
|
||||
/* get parent */
|
||||
rc = bdb_dn2entry_r( be, ltid, &pdn, &p, &matched, 0 );
|
||||
rc = bdb_dn2entry_r( be, ltid, &pdn, &p, &matched, 0, locker, &lock );
|
||||
|
||||
switch( rc ) {
|
||||
case 0:
|
||||
@ -169,7 +173,7 @@ retry: /* transaction retry */
|
||||
refs = is_entry_referral( matched )
|
||||
? get_entry_referrals( be, conn, op, matched )
|
||||
: NULL;
|
||||
bdb_cache_return_entry_r(&bdb->bi_cache, matched);
|
||||
bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache, matched, &lock);
|
||||
matched = NULL;
|
||||
|
||||
} else {
|
||||
@ -200,7 +204,7 @@ retry: /* transaction retry */
|
||||
case DB_LOCK_DEADLOCK:
|
||||
case DB_LOCK_NOTGRANTED:
|
||||
/* free parent and reader lock */
|
||||
bdb_cache_return_entry_r( &bdb->bi_cache, p );
|
||||
bdb_cache_return_entry_r( bdb->bi_dbenv, &bdb->bi_cache, p, &lock );
|
||||
p = NULL;
|
||||
goto retry;
|
||||
}
|
||||
@ -262,7 +266,7 @@ retry: /* transaction retry */
|
||||
matched_dn, NULL, refs, NULL );
|
||||
|
||||
ber_bvarray_free( refs );
|
||||
bdb_cache_return_entry_r( &bdb->bi_cache, p );
|
||||
bdb_cache_return_entry_r( bdb->bi_dbenv, &bdb->bi_cache, p, &lock );
|
||||
p = NULL;
|
||||
goto done;
|
||||
}
|
||||
@ -275,7 +279,7 @@ retry: /* transaction retry */
|
||||
#endif
|
||||
|
||||
/* free parent and reader lock */
|
||||
bdb_cache_return_entry_r( &bdb->bi_cache, p );
|
||||
bdb_cache_return_entry_r( bdb->bi_dbenv, &bdb->bi_cache, p, &lock );
|
||||
p = NULL;
|
||||
|
||||
} else {
|
||||
@ -430,9 +434,22 @@ retry: /* transaction retry */
|
||||
text = "txn_prepare failed";
|
||||
|
||||
} else {
|
||||
ret = bdb_cache_add_entry_rw(bdb->bi_dbenv, &bdb->bi_cache, e, CACHE_WRITE_LOCK, locker, &lock);
|
||||
#if 0
|
||||
if ( bdb_cache_add_entry_rw(&bdb->bi_cache,
|
||||
e, CACHE_WRITE_LOCK) != 0 )
|
||||
{
|
||||
#endif
|
||||
switch ( ret ) {
|
||||
case 0:
|
||||
break;
|
||||
case DB_LOCK_DEADLOCK:
|
||||
case DB_LOCK_NOTGRANTED:
|
||||
goto retry;
|
||||
default:
|
||||
ret = LDAP_OTHER;
|
||||
}
|
||||
|
||||
if ( ret ) {
|
||||
if(( rc=TXN_ABORT( ltid )) != 0 ) {
|
||||
text = "cache add & txn_abort failed";
|
||||
} else {
|
||||
|
@ -39,6 +39,9 @@ bdb_attribute(
|
||||
const char *entry_at_name = entry_at->ad_cname.bv_val;
|
||||
AccessControlState acl_state = ACL_STATE_INIT;
|
||||
|
||||
u_int32_t locker;
|
||||
DB_LOCK lock;
|
||||
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG(( "backend", LDAP_LEVEL_ARGS,
|
||||
"bdb_attribute: gr dn: \"%s\"\n", entry_ndn->bv_val ));
|
||||
@ -65,6 +68,11 @@ bdb_attribute(
|
||||
txn = boi->boi_txn;
|
||||
}
|
||||
|
||||
if ( txn != NULL )
|
||||
locker = TXN_ID ( txn );
|
||||
else
|
||||
LOCK_ID ( bdb->bi_dbenv, &locker );
|
||||
|
||||
if (target != NULL && dn_match(&target->e_nname, entry_ndn)) {
|
||||
/* we already have a LOCKED copy of the entry */
|
||||
e = target;
|
||||
@ -80,16 +88,23 @@ bdb_attribute(
|
||||
|
||||
|
||||
} else {
|
||||
dn2entry_retry:
|
||||
/* can we find entry */
|
||||
rc = bdb_dn2entry_r( be, NULL, entry_ndn, &e, NULL, 0 );
|
||||
rc = bdb_dn2entry_r( be, NULL, entry_ndn, &e, NULL, 0, locker, &lock );
|
||||
switch( rc ) {
|
||||
case DB_NOTFOUND:
|
||||
case 0:
|
||||
break;
|
||||
case DB_LOCK_DEADLOCK:
|
||||
case DB_LOCK_NOTGRANTED:
|
||||
goto dn2entry_retry;
|
||||
default:
|
||||
if( txn != NULL ) {
|
||||
boi->boi_err = rc;
|
||||
}
|
||||
else {
|
||||
LOCK_ID_FREE( bdb->bi_dbenv, locker );
|
||||
}
|
||||
return (rc != LDAP_BUSY) ? LDAP_OTHER : LDAP_BUSY;
|
||||
}
|
||||
if (e == NULL) {
|
||||
@ -102,6 +117,9 @@ bdb_attribute(
|
||||
"=> bdb_attribute: cannot find entry: \"%s\"\n",
|
||||
entry_ndn->bv_val, 0, 0 );
|
||||
#endif
|
||||
if ( txn == NULL ) {
|
||||
LOCK_ID_FREE( bdb->bi_dbenv, locker );
|
||||
}
|
||||
return LDAP_NO_SUCH_OBJECT;
|
||||
}
|
||||
|
||||
@ -205,7 +223,11 @@ bdb_attribute(
|
||||
return_results:
|
||||
if( target != e ) {
|
||||
/* free entry */
|
||||
bdb_cache_return_entry_r(&bdb->bi_cache, e);
|
||||
bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache, e, &lock);
|
||||
}
|
||||
|
||||
if ( txn == NULL ) {
|
||||
LOCK_ID_FREE( bdb->bi_dbenv, locker );
|
||||
}
|
||||
|
||||
#ifdef NEW_LOGGING
|
||||
|
@ -146,21 +146,27 @@ struct bdb_op_info {
|
||||
#if DB_VERSION_MAJOR < 4
|
||||
#define LOCK_DETECT(env,f,t,a) lock_detect(env, f, t, a)
|
||||
#define LOCK_GET(env,i,f,o,m,l) lock_get(env, i, f, o, m, l)
|
||||
#define LOCK_PUT(env,l) lock_put(env, l)
|
||||
#define TXN_CHECKPOINT(env,k,m,f) txn_checkpoint(env, k, m, f)
|
||||
#define TXN_BEGIN(env,p,t,f) txn_begin((env), p, t, f)
|
||||
#define TXN_PREPARE(txn,gid) txn_prepare((txn), (gid))
|
||||
#define TXN_COMMIT(txn,f) txn_commit((txn), (f))
|
||||
#define TXN_ABORT(txn) txn_abort((txn))
|
||||
#define TXN_ID(txn) txn_id(txn)
|
||||
#define LOCK_ID(env, locker) lock_id(env, locker)
|
||||
#define LOCK_ID_FREE(env, locker) lock_id_free(env, locker)
|
||||
#else
|
||||
#define LOCK_DETECT(env,f,t,a) (env)->lock_detect(env, f, t, a)
|
||||
#define LOCK_GET(env,i,f,o,m,l) (env)->lock_get(env, i, f, o, m, l)
|
||||
#define LOCK_PUT(env,l) (env)->lock_put(env, l)
|
||||
#define TXN_CHECKPOINT(env,k,m,f) (env)->txn_checkpoint(env, k, m, f)
|
||||
#define TXN_BEGIN(env,p,t,f) (env)->txn_begin((env), p, t, f)
|
||||
#define TXN_PREPARE(txn,g) (txn)->prepare((txn), (g))
|
||||
#define TXN_COMMIT(txn,f) (txn)->commit((txn), (f))
|
||||
#define TXN_ABORT(txn) (txn)->abort((txn))
|
||||
#define TXN_ID(txn) (txn)->id(txn)
|
||||
#define LOCK_ID(env, locker) (env)->lock_id(env, locker)
|
||||
#define LOCK_ID_FREE(env, locker) (env)->lock_id_free(env, locker)
|
||||
#endif
|
||||
|
||||
LDAP_END_DECL
|
||||
|
@ -40,14 +40,20 @@ bdb_bind(
|
||||
|
||||
AttributeDescription *password = slap_schema.si_ad_userPassword;
|
||||
|
||||
u_int32_t locker;
|
||||
DB_LOCK lock;
|
||||
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG (( "bind", LDAP_LEVEL_ARGS, "==> bdb_bind: dn: %s\n", dn->bv_val ));
|
||||
#else
|
||||
Debug( LDAP_DEBUG_ARGS, "==> bdb_bind: dn: %s\n", dn->bv_val, 0, 0);
|
||||
#endif
|
||||
|
||||
LOCK_ID(bdb->bi_dbenv, &locker);
|
||||
|
||||
dn2entry_retry:
|
||||
/* get entry */
|
||||
rc = bdb_dn2entry_r( be, NULL, ndn, &e, &matched, 0 );
|
||||
rc = bdb_dn2entry_r( be, NULL, ndn, &e, &matched, 0, locker, &lock );
|
||||
|
||||
switch(rc) {
|
||||
case DB_NOTFOUND:
|
||||
@ -56,10 +62,15 @@ bdb_bind(
|
||||
case LDAP_BUSY:
|
||||
send_ldap_result( conn, op, LDAP_BUSY,
|
||||
NULL, "ldap server busy", NULL, NULL );
|
||||
LOCK_ID_FREE(bdb->bi_dbenv, locker);
|
||||
return LDAP_BUSY;
|
||||
case DB_LOCK_DEADLOCK:
|
||||
case DB_LOCK_NOTGRANTED:
|
||||
goto dn2entry_retry;
|
||||
default:
|
||||
send_ldap_result( conn, op, rc=LDAP_OTHER,
|
||||
NULL, "internal error", NULL, NULL );
|
||||
LOCK_ID_FREE(bdb->bi_dbenv, locker);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -75,7 +86,7 @@ bdb_bind(
|
||||
? get_entry_referrals( be, conn, op, matched )
|
||||
: NULL;
|
||||
|
||||
bdb_cache_return_entry_r( &bdb->bi_cache, matched );
|
||||
bdb_cache_return_entry_r( bdb->bi_dbenv, &bdb->bi_cache, matched, &lock );
|
||||
matched = NULL;
|
||||
|
||||
} else {
|
||||
@ -108,6 +119,8 @@ bdb_bind(
|
||||
NULL, NULL, NULL, NULL );
|
||||
}
|
||||
|
||||
LOCK_ID_FREE(bdb->bi_dbenv, locker);
|
||||
|
||||
ber_bvarray_free( refs );
|
||||
free( matched_dn );
|
||||
|
||||
@ -274,9 +287,11 @@ bdb_bind(
|
||||
done:
|
||||
/* free entry and reader lock */
|
||||
if( e != NULL ) {
|
||||
bdb_cache_return_entry_r( &bdb->bi_cache, e );
|
||||
bdb_cache_return_entry_r( bdb->bi_dbenv, &bdb->bi_cache, e, &lock );
|
||||
}
|
||||
|
||||
LOCK_ID_FREE(bdb->bi_dbenv, locker);
|
||||
|
||||
/* front end with send result on success (rc==0) */
|
||||
return rc;
|
||||
}
|
||||
|
@ -132,6 +132,36 @@ bdb_cache_entry_private_init( Entry *e )
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
bdb_cache_entry_db_lock
|
||||
( DB_ENV *env, u_int32_t locker, Entry *e, int rw, u_int32_t flags, DB_LOCK *lock )
|
||||
{
|
||||
int rc;
|
||||
DBT lockobj;
|
||||
int db_rw;
|
||||
|
||||
if (rw)
|
||||
db_rw = DB_LOCK_WRITE;
|
||||
else
|
||||
db_rw = DB_LOCK_READ;
|
||||
|
||||
lockobj.data = e->e_nname.bv_val;
|
||||
lockobj.size = e->e_nname.bv_len;
|
||||
rc = LOCK_GET(env, locker, flags | DB_LOCK_NOWAIT,
|
||||
&lockobj, db_rw, lock);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
bdb_cache_entry_db_unlock
|
||||
( DB_ENV *env, DB_LOCK *lock )
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = LOCK_PUT ( env, lock );
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* marks an entry in CREATING state as committed, so it is really returned
|
||||
* to the cache. Otherwise an entry in CREATING state is removed.
|
||||
@ -162,7 +192,110 @@ bdb_cache_entry_private_destroy( Entry *e )
|
||||
}
|
||||
|
||||
void
|
||||
bdb_cache_return_entry_rw( Cache *cache, Entry *e, int rw )
|
||||
bdb_unlocked_cache_return_entry_rw( Cache *cache, Entry *e, int rw )
|
||||
{
|
||||
|
||||
ID id;
|
||||
int refcnt, freeit = 1;
|
||||
|
||||
/* set cache write lock */
|
||||
ldap_pvt_thread_rdwr_wlock( &cache->c_rwlock );
|
||||
|
||||
assert( e->e_private );
|
||||
|
||||
#if 0
|
||||
bdb_cache_entry_rdwr_unlock(e, rw);
|
||||
#endif
|
||||
|
||||
id = e->e_id;
|
||||
refcnt = --BEI(e)->bei_refcnt;
|
||||
|
||||
/*
|
||||
* if the entry is returned when in CREATING state, it is deleted
|
||||
* but not freed because it may belong to someone else (do_add,
|
||||
* for instance)
|
||||
*/
|
||||
if ( BEI(e)->bei_state == CACHE_ENTRY_CREATING ) {
|
||||
/* set lru mutex */
|
||||
ldap_pvt_thread_mutex_lock( &cache->lru_mutex );
|
||||
bdb_cache_delete_entry_internal( cache, e );
|
||||
/* free lru mutex */
|
||||
ldap_pvt_thread_mutex_unlock( &cache->lru_mutex );
|
||||
freeit = 0;
|
||||
/* now the entry is in DELETED state */
|
||||
}
|
||||
|
||||
if ( BEI(e)->bei_state == CACHE_ENTRY_COMMITTED ) {
|
||||
BEI(e)->bei_state = CACHE_ENTRY_READY;
|
||||
|
||||
/* free cache write lock */
|
||||
ldap_pvt_thread_rdwr_wunlock( &cache->c_rwlock );
|
||||
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG(( "cache", LDAP_LEVEL_DETAIL1,
|
||||
"bdb_cache_return_entry_rw: return (%ld):%s, refcnt=%d\n",
|
||||
id, rw ? "w" : "r", refcnt ));
|
||||
#else
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"====> bdb_cache_return_entry_%s( %ld ): created (%d)\n",
|
||||
rw ? "w" : "r", id, refcnt );
|
||||
#endif
|
||||
|
||||
|
||||
} else if ( BEI(e)->bei_state == CACHE_ENTRY_DELETED ) {
|
||||
if( refcnt > 0 ) {
|
||||
/* free cache write lock */
|
||||
ldap_pvt_thread_rdwr_wunlock( &cache->c_rwlock );
|
||||
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG(( "cache", LDAP_LEVEL_DETAIL1,
|
||||
"bdb_cache_return_entry_rw: %ld, delete pending (%d).\n",
|
||||
id, refcnt ));
|
||||
#else
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"====> bdb_cache_return_entry_%s( %ld ): delete pending (%d)\n",
|
||||
rw ? "w" : "r", id, refcnt );
|
||||
#endif
|
||||
|
||||
} else {
|
||||
bdb_cache_entry_private_destroy( e );
|
||||
if ( freeit ) {
|
||||
bdb_entry_return( e );
|
||||
}
|
||||
|
||||
/* free cache write lock */
|
||||
ldap_pvt_thread_rdwr_wunlock( &cache->c_rwlock );
|
||||
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG(( "cache", LDAP_LEVEL_DETAIL1,
|
||||
"bdb_cache_return_entry_rw: (%ld): deleted (%d)\n",
|
||||
id, refcnt ));
|
||||
#else
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"====> bdb_cache_return_entry_%s( %ld ): deleted (%d)\n",
|
||||
rw ? "w" : "r", id, refcnt );
|
||||
#endif
|
||||
}
|
||||
|
||||
} else {
|
||||
/* free cache write lock */
|
||||
ldap_pvt_thread_rdwr_wunlock( &cache->c_rwlock );
|
||||
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG(( "cache", LDAP_LEVEL_DETAIL1,
|
||||
"bdb_cache_return_entry_rw: ID %ld:%s returned (%d)\n",
|
||||
id, rw ? "w": "r", refcnt ));
|
||||
#else
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"====> bdb_cache_return_entry_%s( %ld ): returned (%d)\n",
|
||||
rw ? "w" : "r", id, refcnt);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
bdb_cache_return_entry_rw
|
||||
( DB_ENV *env, Cache *cache, Entry *e, int rw, DB_LOCK *lock )
|
||||
{
|
||||
ID id;
|
||||
int refcnt, freeit = 1;
|
||||
@ -172,7 +305,10 @@ bdb_cache_return_entry_rw( Cache *cache, Entry *e, int rw )
|
||||
|
||||
assert( e->e_private );
|
||||
|
||||
bdb_cache_entry_db_unlock( env, lock );
|
||||
#if 0
|
||||
bdb_cache_entry_rdwr_unlock(e, rw);
|
||||
#endif
|
||||
|
||||
id = e->e_id;
|
||||
refcnt = --BEI(e)->bei_refcnt;
|
||||
@ -290,12 +426,16 @@ bdb_cache_return_entry_rw( Cache *cache, Entry *e, int rw )
|
||||
* returns: 0 entry has been created and locked
|
||||
* 1 entry already existed
|
||||
* -1 something bad happened
|
||||
* other Berkeley DB locking error code
|
||||
*/
|
||||
int
|
||||
bdb_cache_add_entry_rw(
|
||||
DB_ENV *env,
|
||||
Cache *cache,
|
||||
Entry *e,
|
||||
int rw
|
||||
int rw,
|
||||
u_int32_t locker,
|
||||
DB_LOCK *lock
|
||||
)
|
||||
{
|
||||
int i, rc;
|
||||
@ -385,7 +525,37 @@ bdb_cache_add_entry_rw(
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
bdb_cache_entry_rdwr_lock( e, rw );
|
||||
rc = bdb_cache_entry_db_lock( env, locker, e, rw, 0, lock );
|
||||
switch ( rc ) {
|
||||
case 0 :
|
||||
break;
|
||||
case DB_LOCK_DEADLOCK :
|
||||
case DB_LOCK_NOTGRANTED :
|
||||
/* undo avl changes immediately */
|
||||
if ( avl_delete( &cache->c_idtree, (caddr_t) e,
|
||||
(AVL_CMP) entry_id_cmp ) == NULL ) {
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG(( "cache", LDAP_LEVEL_INFO,
|
||||
"bdb_cache_add_entry: can't delete (%s) from cache.\n", e->e_dn ));
|
||||
#else
|
||||
Debug( LDAP_DEBUG_ANY, "====> can't delete from id cache\n", 0, 0, 0 );
|
||||
#endif
|
||||
}
|
||||
if ( avl_delete( &cache->c_dntree, (caddr_t) e,
|
||||
(AVL_CMP) entry_dn_cmp ) == NULL ) {
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG(( "cache", LDAP_LEVEL_INFO,
|
||||
"bdb_cache_add_entry: can't delete (%s) from cache.\n", e->e_dn ));
|
||||
#else
|
||||
Debug( LDAP_DEBUG_ANY, "====> can't delete from dn cache\n", 0, 0, 0 );
|
||||
#endif
|
||||
}
|
||||
/* fall through */
|
||||
default :
|
||||
bdb_cache_entry_private_destroy(e);
|
||||
ldap_pvt_thread_rdwr_wunlock( &cache->c_rwlock );
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* put the entry into 'CREATING' state */
|
||||
/* will be marked after when entry is returned */
|
||||
@ -661,14 +831,18 @@ try_again:
|
||||
|
||||
Entry *
|
||||
bdb_cache_find_entry_id(
|
||||
DB_ENV *env,
|
||||
Cache *cache,
|
||||
ID id,
|
||||
int rw
|
||||
int rw,
|
||||
u_int32_t locker,
|
||||
DB_LOCK *lock
|
||||
)
|
||||
{
|
||||
Entry e;
|
||||
Entry *ep;
|
||||
int count = 0;
|
||||
int rc;
|
||||
|
||||
e.e_id = id;
|
||||
|
||||
@ -715,7 +889,13 @@ try_again:
|
||||
}
|
||||
|
||||
/* acquire reader lock */
|
||||
rc = bdb_cache_entry_db_lock ( env, locker, ep, rw, 0, lock );
|
||||
|
||||
#if 0
|
||||
if ( bdb_cache_entry_rdwr_trylock(ep, rw) == LDAP_PVT_THREAD_EBUSY ) {
|
||||
#endif
|
||||
|
||||
if ( rc ) { /* will be changed to retry beyond threshold */
|
||||
/* could not acquire entry lock...
|
||||
* owner cannot free as we have the cache locked.
|
||||
* so, unlock the cache, yield, and try again.
|
||||
@ -732,6 +912,9 @@ try_again:
|
||||
Debug(LDAP_DEBUG_TRACE,
|
||||
"====> bdb_cache_find_entry_id( %ld ): %ld (busy) %d\n",
|
||||
id, ep_id, state);
|
||||
Debug(LDAP_DEBUG_TRACE,
|
||||
"locker = %d\n",
|
||||
locker, 0, 0);
|
||||
#endif
|
||||
|
||||
ldap_pvt_thread_yield();
|
||||
|
@ -31,8 +31,14 @@ bdb_compare(
|
||||
const char *text = NULL;
|
||||
int manageDSAit = get_manageDSAit( op );
|
||||
|
||||
u_int32_t locker;
|
||||
DB_LOCK lock;
|
||||
|
||||
LOCK_ID ( bdb->bi_dbenv, &locker );
|
||||
|
||||
dn2entry_retry:
|
||||
/* get entry */
|
||||
rc = bdb_dn2entry_r( be, NULL, ndn, &e, &matched, 0 );
|
||||
rc = bdb_dn2entry_r( be, NULL, ndn, &e, &matched, 0, locker, &lock );
|
||||
|
||||
switch( rc ) {
|
||||
case DB_NOTFOUND:
|
||||
@ -41,6 +47,9 @@ bdb_compare(
|
||||
case LDAP_BUSY:
|
||||
text = "ldap server busy";
|
||||
goto return_results;
|
||||
case DB_LOCK_DEADLOCK:
|
||||
case DB_LOCK_NOTGRANTED:
|
||||
goto dn2entry_retry;
|
||||
default:
|
||||
rc = LDAP_OTHER;
|
||||
text = "internal error";
|
||||
@ -56,7 +65,7 @@ bdb_compare(
|
||||
refs = is_entry_referral( matched )
|
||||
? get_entry_referrals( be, conn, op, matched )
|
||||
: NULL;
|
||||
bdb_cache_return_entry_r( &bdb->bi_cache, matched );
|
||||
bdb_cache_return_entry_r( bdb->bi_dbenv, &bdb->bi_cache, matched, &lock );
|
||||
matched = NULL;
|
||||
|
||||
} else {
|
||||
@ -125,8 +134,10 @@ return_results:
|
||||
done:
|
||||
/* free entry */
|
||||
if( e != NULL ) {
|
||||
bdb_cache_return_entry_r( &bdb->bi_cache, e );
|
||||
bdb_cache_return_entry_r( bdb->bi_dbenv, &bdb->bi_cache, e, &lock );
|
||||
}
|
||||
|
||||
LOCK_ID_FREE ( bdb->bi_dbenv, locker );
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
@ -33,6 +33,9 @@ bdb_delete(
|
||||
AttributeDescription *children = slap_schema.si_ad_children;
|
||||
DB_TXN *ltid = NULL;
|
||||
struct bdb_op_info opinfo;
|
||||
|
||||
u_int32_t locker;
|
||||
DB_LOCK lock;
|
||||
#if 0
|
||||
u_int32_t lockid;
|
||||
DB_LOCK lock;
|
||||
@ -49,7 +52,7 @@ bdb_delete(
|
||||
if( 0 ) {
|
||||
retry: /* transaction retry */
|
||||
if( e != NULL ) {
|
||||
bdb_cache_return_entry_w(&bdb->bi_cache, e);
|
||||
bdb_cache_return_entry_w(bdb->bi_dbenv, &bdb->bi_cache, e, &lock);
|
||||
}
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG (( "delete", LDAP_LEVEL_DETAIL1,
|
||||
@ -87,6 +90,8 @@ retry: /* transaction retry */
|
||||
text = "internal error";
|
||||
goto return_results;
|
||||
}
|
||||
|
||||
locker = TXN_ID ( ltid );
|
||||
#if 0
|
||||
lockid = TXN_ID( ltid );
|
||||
#endif
|
||||
@ -111,7 +116,7 @@ retry: /* transaction retry */
|
||||
}
|
||||
#endif
|
||||
/* get parent */
|
||||
rc = bdb_dn2entry_r( be, ltid, &pdn, &p, NULL, 0 );
|
||||
rc = bdb_dn2entry_r( be, ltid, &pdn, &p, NULL, 0, locker, &lock );
|
||||
|
||||
switch( rc ) {
|
||||
case 0:
|
||||
@ -147,7 +152,7 @@ retry: /* transaction retry */
|
||||
rc = access_allowed( be, conn, op, p,
|
||||
children, NULL, ACL_WRITE, NULL );
|
||||
|
||||
bdb_cache_return_entry_r(&bdb->bi_cache, p);
|
||||
bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache, p, &lock);
|
||||
p = NULL;
|
||||
|
||||
switch( opinfo.boi_err ) {
|
||||
@ -226,7 +231,7 @@ retry: /* transaction retry */
|
||||
}
|
||||
|
||||
/* get entry for read/modify/write */
|
||||
rc = bdb_dn2entry_w( be, ltid, ndn, &e, &matched, DB_RMW );
|
||||
rc = bdb_dn2entry_w( be, ltid, ndn, &e, &matched, DB_RMW, locker, &lock );
|
||||
|
||||
switch( rc ) {
|
||||
case 0:
|
||||
@ -263,7 +268,7 @@ retry: /* transaction retry */
|
||||
refs = is_entry_referral( matched )
|
||||
? get_entry_referrals( be, conn, op, matched )
|
||||
: NULL;
|
||||
bdb_cache_return_entry_r(&bdb->bi_cache, matched );
|
||||
bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache, matched, &lock );
|
||||
matched = NULL;
|
||||
|
||||
} else {
|
||||
@ -465,7 +470,7 @@ return_results:
|
||||
done:
|
||||
/* free entry */
|
||||
if( e != NULL ) {
|
||||
bdb_cache_return_entry_w(&bdb->bi_cache, e);
|
||||
bdb_cache_return_entry_w(bdb->bi_dbenv, &bdb->bi_cache, e, &lock);
|
||||
}
|
||||
|
||||
if( ltid != NULL ) {
|
||||
|
@ -25,7 +25,9 @@ bdb_dn2entry_rw(
|
||||
Entry **e,
|
||||
Entry **matched,
|
||||
int flags,
|
||||
int rw )
|
||||
int rw,
|
||||
u_int32_t locker,
|
||||
DB_LOCK *lock )
|
||||
{
|
||||
int rc;
|
||||
ID id, id2 = 0;
|
||||
@ -52,9 +54,9 @@ bdb_dn2entry_rw(
|
||||
}
|
||||
|
||||
if( id2 == 0 ) {
|
||||
rc = bdb_id2entry_rw( be, tid, id, e, rw );
|
||||
rc = bdb_id2entry_rw( be, tid, id, e, rw, locker, lock );
|
||||
} else {
|
||||
rc = bdb_id2entry_r( be, tid, id2, matched);
|
||||
rc = bdb_id2entry_r( be, tid, id2, matched, locker, lock );
|
||||
}
|
||||
|
||||
return rc;
|
||||
|
@ -44,6 +44,9 @@ bdb_group(
|
||||
const char *group_oc_name = NULL;
|
||||
const char *group_at_name = group_at->ad_cname.bv_val;
|
||||
|
||||
u_int32_t locker;
|
||||
DB_LOCK lock;
|
||||
|
||||
if( group_oc->soc_names && group_oc->soc_names[0] ) {
|
||||
group_oc_name = group_oc->soc_names[0];
|
||||
} else {
|
||||
@ -76,6 +79,11 @@ bdb_group(
|
||||
txn = boi->boi_txn;
|
||||
}
|
||||
|
||||
if ( txn )
|
||||
locker = TXN_ID( txn );
|
||||
else
|
||||
LOCK_ID ( bdb->bi_dbenv, &locker );
|
||||
|
||||
if (dn_match(&target->e_name, gr_ndn)) {
|
||||
/* we already have a LOCKED copy of the entry */
|
||||
e = target;
|
||||
@ -88,12 +96,18 @@ bdb_group(
|
||||
gr_ndn->bv_val, 0, 0 );
|
||||
#endif
|
||||
} else {
|
||||
dn2entry_retry:
|
||||
/* can we find group entry */
|
||||
rc = bdb_dn2entry_r( be, NULL, gr_ndn, &e, NULL, 0 );
|
||||
rc = bdb_dn2entry_r( be, NULL, gr_ndn, &e, NULL, 0, locker, &lock );
|
||||
if( rc ) {
|
||||
if ( rc == DB_LOCK_DEADLOCK || rc == DB_LOCK_NOTGRANTED )
|
||||
goto dn2entry_retry;
|
||||
if( txn ) {
|
||||
boi->boi_err = rc;
|
||||
}
|
||||
else {
|
||||
LOCK_ID_FREE ( bdb->bi_dbenv, locker );
|
||||
}
|
||||
return( 1 );
|
||||
}
|
||||
if (e == NULL) {
|
||||
@ -106,6 +120,9 @@ bdb_group(
|
||||
"=> bdb_group: cannot find group: \"%s\"\n",
|
||||
gr_ndn->bv_val, 0, 0 );
|
||||
#endif
|
||||
if ( txn == NULL ) {
|
||||
LOCK_ID_FREE ( bdb->bi_dbenv, locker );
|
||||
}
|
||||
return( 1 );
|
||||
}
|
||||
#ifdef NEW_LOGGING
|
||||
@ -211,7 +228,11 @@ bdb_group(
|
||||
return_results:
|
||||
if( target != e ) {
|
||||
/* free entry */
|
||||
bdb_cache_return_entry_r( &bdb->bi_cache, e );
|
||||
bdb_cache_return_entry_r( bdb->bi_dbenv, &bdb->bi_cache, e, &lock );
|
||||
}
|
||||
|
||||
if ( txn == NULL ) {
|
||||
LOCK_ID_FREE ( bdb->bi_dbenv, locker );
|
||||
}
|
||||
|
||||
#ifdef NEW_LOGGING
|
||||
|
@ -80,13 +80,15 @@ int bdb_id2entry_rw(
|
||||
DB_TXN *tid,
|
||||
ID id,
|
||||
Entry **e,
|
||||
int rw )
|
||||
int rw,
|
||||
u_int32_t locker,
|
||||
DB_LOCK *lock )
|
||||
{
|
||||
struct bdb_info *bdb = (struct bdb_info *) be->be_private;
|
||||
DB *db = bdb->bi_id2entry->bdi_db;
|
||||
DBT key, data;
|
||||
struct berval bv;
|
||||
int rc = 0;
|
||||
int rc = 0, ret = 0;
|
||||
|
||||
*e = NULL;
|
||||
|
||||
@ -97,7 +99,7 @@ int bdb_id2entry_rw(
|
||||
DBTzero( &data );
|
||||
data.flags = DB_DBT_MALLOC;
|
||||
|
||||
if ((*e = bdb_cache_find_entry_id(&bdb->bi_cache, id, rw)) != NULL) {
|
||||
if ((*e = bdb_cache_find_entry_id(bdb->bi_dbenv, &bdb->bi_cache, id, rw, locker, lock)) != NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -121,24 +123,36 @@ int bdb_id2entry_rw(
|
||||
ch_free( data.data );
|
||||
}
|
||||
|
||||
while (rc == 0 && bdb_cache_add_entry_rw(&bdb->bi_cache, *e, rw) != 0) {
|
||||
Entry *ee;
|
||||
int add_loop_cnt = 0;
|
||||
if ( (*e)->e_private != NULL ) {
|
||||
free ((*e)->e_private);
|
||||
if ( rc == 0 ) {
|
||||
ret = bdb_cache_add_entry_rw( bdb->bi_dbenv,
|
||||
&bdb->bi_cache, *e, rw, locker, lock);
|
||||
while ( ret == 1 || ret == -1 ) {
|
||||
Entry *ee;
|
||||
int add_loop_cnt = 0;
|
||||
if ( (*e)->e_private != NULL ) {
|
||||
free ((*e)->e_private);
|
||||
}
|
||||
(*e)->e_private = NULL;
|
||||
if ( (ee = bdb_cache_find_entry_id
|
||||
(bdb->bi_dbenv, &bdb->bi_cache, id, rw, locker, lock) ) != NULL) {
|
||||
bdb_entry_return ( *e );
|
||||
*e = ee;
|
||||
return 0;
|
||||
}
|
||||
if ( ++add_loop_cnt == BDB_MAX_ADD_LOOP ) {
|
||||
bdb_entry_return ( *e );
|
||||
*e = NULL;
|
||||
return LDAP_BUSY;
|
||||
}
|
||||
}
|
||||
(*e)->e_private = NULL;
|
||||
if ( (ee = bdb_cache_find_entry_id
|
||||
(&bdb->bi_cache, id, rw) ) != NULL) {
|
||||
bdb_entry_return ( *e );
|
||||
*e = ee;
|
||||
return 0;
|
||||
}
|
||||
if ( ++add_loop_cnt == BDB_MAX_ADD_LOOP ) {
|
||||
bdb_entry_return ( *e );
|
||||
if ( ret != 0 ) {
|
||||
if ( (*e)->e_private != NULL )
|
||||
free ( (*e)->e_private );
|
||||
bdb_entry_return( *e );
|
||||
*e = NULL;
|
||||
return LDAP_BUSY;
|
||||
ch_free( data.data );
|
||||
}
|
||||
rc = ret;
|
||||
}
|
||||
|
||||
#ifdef BDB_HIER
|
||||
@ -232,7 +246,7 @@ int bdb_entry_release(
|
||||
|
||||
if ( slapMode == SLAP_SERVER_MODE ) {
|
||||
/* free entry and reader or writer lock */
|
||||
bdb_cache_return_entry_rw( &bdb->bi_cache, e, rw );
|
||||
bdb_unlocked_cache_return_entry_rw( &bdb->bi_cache, e, rw );
|
||||
} else {
|
||||
if (e->e_private != NULL)
|
||||
free (e->e_private);
|
||||
|
@ -249,6 +249,9 @@ bdb_modify(
|
||||
DB_TXN *ltid = NULL;
|
||||
struct bdb_op_info opinfo;
|
||||
|
||||
u_int32_t locker;
|
||||
DB_LOCK lock;
|
||||
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG (( "modify", LDAP_LEVEL_ENTRY, "bdb_modify: %s\n", dn->bv_val ));
|
||||
#else
|
||||
@ -259,7 +262,7 @@ bdb_modify(
|
||||
retry: /* transaction retry */
|
||||
if( e != NULL ) {
|
||||
bdb_cache_delete_entry(&bdb->bi_cache, e);
|
||||
bdb_cache_return_entry_w(&bdb->bi_cache, e);
|
||||
bdb_cache_return_entry_w(bdb->bi_dbenv, &bdb->bi_cache, e, &lock);
|
||||
}
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG (( "modify", LDAP_LEVEL_DETAIL1, "bdb_modify: retrying...\n" ));
|
||||
@ -295,13 +298,15 @@ retry: /* transaction retry */
|
||||
goto return_results;
|
||||
}
|
||||
|
||||
locker = TXN_ID ( ltid );
|
||||
|
||||
opinfo.boi_bdb = be;
|
||||
opinfo.boi_txn = ltid;
|
||||
opinfo.boi_err = 0;
|
||||
op->o_private = &opinfo;
|
||||
|
||||
/* get entry */
|
||||
rc = bdb_dn2entry_w( be, ltid, ndn, &e, &matched, 0 );
|
||||
rc = bdb_dn2entry_w( be, ltid, ndn, &e, &matched, 0, locker, &lock );
|
||||
|
||||
if ( rc != 0 ) {
|
||||
#ifdef NEW_LOGGING
|
||||
@ -337,7 +342,7 @@ retry: /* transaction retry */
|
||||
refs = is_entry_referral( matched )
|
||||
? get_entry_referrals( be, conn, op, matched )
|
||||
: NULL;
|
||||
bdb_cache_return_entry_r (&bdb->bi_cache, matched);
|
||||
bdb_cache_return_entry_r (bdb->bi_dbenv, &bdb->bi_cache, matched, &lock);
|
||||
matched = NULL;
|
||||
|
||||
} else {
|
||||
@ -463,7 +468,7 @@ done:
|
||||
}
|
||||
|
||||
if( e != NULL ) {
|
||||
bdb_cache_return_entry_w (&bdb->bi_cache, e);
|
||||
bdb_cache_return_entry_w (bdb->bi_dbenv, &bdb->bi_cache, e, &lock);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
@ -56,6 +56,9 @@ bdb_modrdn(
|
||||
|
||||
int manageDSAit = get_manageDSAit( op );
|
||||
|
||||
u_int32_t locker;
|
||||
DB_LOCK lock;
|
||||
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG (( "modrdn", LDAP_LEVEL_ENTRY, "==>bdb_modrdn(%s,%s,%s)\n",
|
||||
dn->bv_val,newrdn->bv_val,
|
||||
@ -78,13 +81,13 @@ bdb_modrdn(
|
||||
retry: /* transaction retry */
|
||||
if (e != NULL) {
|
||||
bdb_cache_delete_entry(&bdb->bi_cache, e);
|
||||
bdb_cache_return_entry_w(&bdb->bi_cache, e);
|
||||
bdb_cache_return_entry_w(bdb->bi_dbenv, &bdb->bi_cache, e, &lock);
|
||||
}
|
||||
if (p != NULL) {
|
||||
bdb_cache_return_entry_r(&bdb->bi_cache, p);
|
||||
bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache, p, &lock);
|
||||
}
|
||||
if (np != NULL) {
|
||||
bdb_cache_return_entry_r(&bdb->bi_cache, np);
|
||||
bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache, np, &lock);
|
||||
}
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG (( "modrdn", LDAP_LEVEL_DETAIL1, "==>bdb_modrdn: retrying...\n"));
|
||||
@ -119,13 +122,15 @@ retry: /* transaction retry */
|
||||
goto return_results;
|
||||
}
|
||||
|
||||
locker = TXN_ID ( ltid );
|
||||
|
||||
opinfo.boi_bdb = be;
|
||||
opinfo.boi_txn = ltid;
|
||||
opinfo.boi_err = 0;
|
||||
op->o_private = &opinfo;
|
||||
|
||||
/* get entry */
|
||||
rc = bdb_dn2entry_w( be, ltid, ndn, &e, &matched, 0 );
|
||||
rc = bdb_dn2entry_w( be, ltid, ndn, &e, &matched, 0, locker, &lock );
|
||||
|
||||
switch( rc ) {
|
||||
case 0:
|
||||
@ -152,7 +157,7 @@ retry: /* transaction retry */
|
||||
refs = is_entry_referral( matched )
|
||||
? get_entry_referrals( be, conn, op, matched )
|
||||
: NULL;
|
||||
bdb_cache_return_entry_r( &bdb->bi_cache, matched );
|
||||
bdb_cache_return_entry_r( bdb->bi_dbenv, &bdb->bi_cache, matched, &lock );
|
||||
matched = NULL;
|
||||
|
||||
} else {
|
||||
@ -199,7 +204,7 @@ retry: /* transaction retry */
|
||||
/* Make sure parent entry exist and we can write its
|
||||
* children.
|
||||
*/
|
||||
rc = bdb_dn2entry_r( be, ltid, &p_ndn, &p, NULL, 0 );
|
||||
rc = bdb_dn2entry_r( be, ltid, &p_ndn, &p, NULL, 0, locker, &lock );
|
||||
|
||||
switch( rc ) {
|
||||
case 0:
|
||||
@ -348,7 +353,7 @@ retry: /* transaction retry */
|
||||
/* newSuperior == entry being moved?, if so ==> ERROR */
|
||||
/* Get Entry with dn=newSuperior. Does newSuperior exist? */
|
||||
|
||||
rc = bdb_dn2entry_r( be, ltid, nnewSuperior, &np, NULL, 0 );
|
||||
rc = bdb_dn2entry_r( be, ltid, nnewSuperior, &np, NULL, 0, locker, &lock );
|
||||
|
||||
switch( rc ) {
|
||||
case 0:
|
||||
@ -855,17 +860,17 @@ done:
|
||||
/* LDAP v3 Support */
|
||||
if( np != NULL ) {
|
||||
/* free new parent and reader lock */
|
||||
bdb_cache_return_entry_r(&bdb->bi_cache, np);
|
||||
bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache, np, &lock);
|
||||
}
|
||||
|
||||
if( p != NULL ) {
|
||||
/* free parent and reader lock */
|
||||
bdb_cache_return_entry_r(&bdb->bi_cache, p);
|
||||
bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache, p, &lock);
|
||||
}
|
||||
|
||||
/* free entry */
|
||||
if( e != NULL ) {
|
||||
bdb_cache_return_entry_w( &bdb->bi_cache, e );
|
||||
bdb_cache_return_entry_w( bdb->bi_dbenv, &bdb->bi_cache, e, &lock );
|
||||
}
|
||||
|
||||
if( ltid != NULL ) {
|
||||
|
@ -44,9 +44,11 @@ bdb_operational(
|
||||
|
||||
if( 0 ) {
|
||||
retry: /* transaction retry */
|
||||
#if 0
|
||||
if( e != NULL ) {
|
||||
bdb_cache_return_entry_w(&bdb->bi_cache, e);
|
||||
bdb_cache_return_entry_w(bdb->bi_dbenv, &bdb->bi_cache, e, &lock);
|
||||
}
|
||||
#endif
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG (( "operational", LDAP_LEVEL_DETAIL1,
|
||||
"=> bdb_operational: retrying...\n" ));
|
||||
|
@ -41,6 +41,9 @@ bdb_exop_passwd(
|
||||
struct berval dn;
|
||||
struct berval ndn;
|
||||
|
||||
u_int32_t locker;
|
||||
DB_LOCK lock;
|
||||
|
||||
assert( reqoid != NULL );
|
||||
assert( strcmp( LDAP_EXOP_MODIFY_PASSWD, reqoid ) == 0 );
|
||||
|
||||
@ -109,7 +112,7 @@ bdb_exop_passwd(
|
||||
retry: /* transaction retry */
|
||||
if ( e != NULL ) {
|
||||
bdb_cache_delete_entry(&bdb->bi_cache, e);
|
||||
bdb_cache_return_entry_w(&bdb->bi_cache, e);
|
||||
bdb_cache_return_entry_w(bdb->bi_dbenv, &bdb->bi_cache, e, &lock);
|
||||
}
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG (( "passwd", LDAP_LEVEL_DETAIL1, "bdb_exop_passwd: retrying...\n" ));
|
||||
@ -144,13 +147,15 @@ retry: /* transaction retry */
|
||||
goto done;
|
||||
}
|
||||
|
||||
locker = TXN_ID ( ltid );
|
||||
|
||||
opinfo.boi_bdb = be;
|
||||
opinfo.boi_txn = ltid;
|
||||
opinfo.boi_err = 0;
|
||||
op->o_private = &opinfo;
|
||||
|
||||
/* get entry */
|
||||
rc = bdb_dn2entry_w( be, ltid, &ndn, &e, NULL, 0 );
|
||||
rc = bdb_dn2entry_w( be, ltid, &ndn, &e, NULL, 0 , locker, &lock);
|
||||
|
||||
switch(rc) {
|
||||
case DB_LOCK_DEADLOCK:
|
||||
@ -256,7 +261,7 @@ retry: /* transaction retry */
|
||||
|
||||
done:
|
||||
if( e != NULL ) {
|
||||
bdb_cache_return_entry_w( &bdb->bi_cache, e );
|
||||
bdb_cache_return_entry_w( bdb->bi_dbenv, &bdb->bi_cache, e, &lock );
|
||||
}
|
||||
|
||||
if( hash.bv_val != NULL ) {
|
||||
|
@ -58,9 +58,9 @@ bdb_db_cache(
|
||||
* dn2entry.c
|
||||
*/
|
||||
int bdb_dn2entry_rw LDAP_P(( BackendDB *be, DB_TXN *tid,
|
||||
struct berval *dn, Entry **e, Entry **matched, int flags, int rw ));
|
||||
#define bdb_dn2entry_r(be, tid, dn, e, m, f) bdb_dn2entry_rw((be), (tid), (dn), (e), (m), (f), 0)
|
||||
#define bdb_dn2entry_w(be, tid, dn, e, m, f) bdb_dn2entry_rw((be), (tid), (dn), (e), (m), (f), 1)
|
||||
struct berval *dn, Entry **e, Entry **matched, int flags, int rw , u_int32_t locker, DB_LOCK *lock));
|
||||
#define bdb_dn2entry_r(be, tid, dn, e, m, f, locker, lock) bdb_dn2entry_rw((be), (tid), (dn), (e), (m), (f), 0, locker, lock)
|
||||
#define bdb_dn2entry_w(be, tid, dn, e, m, f, locker, lock) bdb_dn2entry_rw((be), (tid), (dn), (e), (m), (f), 1, locker, lock)
|
||||
|
||||
/*
|
||||
* dn2id.c
|
||||
@ -152,9 +152,11 @@ int bdb_id2entry_rw(
|
||||
DB_TXN *tid,
|
||||
ID id,
|
||||
Entry **e,
|
||||
int rw );
|
||||
#define bdb_id2entry_r(be, tid, id, e) bdb_id2entry_rw((be), (tid), (id), (e), 0)
|
||||
#define bdb_id2entry_w(be, tid, id, e) bdb_id2entry_rw((be), (tid), (id), (e), 1)
|
||||
int rw,
|
||||
u_int32_t locker,
|
||||
DB_LOCK *lock );
|
||||
#define bdb_id2entry_r(be, tid, id, e, locker, lock) bdb_id2entry_rw((be), (tid), (id), (e), 0, locker, lock)
|
||||
#define bdb_id2entry_w(be, tid, id, e, locker, lock) bdb_id2entry_rw((be), (tid), (id), (e), 1, locker, lock)
|
||||
|
||||
void bdb_entry_free ( Entry *e );
|
||||
|
||||
@ -301,13 +303,19 @@ BI_op_extended bdb_exop_passwd;
|
||||
*/
|
||||
|
||||
void bdb_cache_entry_commit( Entry *e );
|
||||
void bdb_cache_return_entry_rw( Cache *cache, Entry *e, int rw );
|
||||
#define bdb_cache_return_entry_r(c, e) bdb_cache_return_entry_rw((c), (e), 0)
|
||||
#define bdb_cache_return_entry_w(c, e) bdb_cache_return_entry_rw((c), (e), 1)
|
||||
void bdb_cache_return_entry_rw( DB_ENV *env, Cache *cache, Entry *e, int rw, DB_LOCK *lock );
|
||||
#define bdb_cache_return_entry_r(env, c, e, l) bdb_cache_return_entry_rw((env), (c), (e), 0, (l))
|
||||
#define bdb_cache_return_entry_w(env, c, e, l) bdb_cache_return_entry_rw((env), (c), (e), 1, (l))
|
||||
void bdb_unlocked_cache_return_entry_rw( Cache *cache, Entry *e, int rw );
|
||||
#define bdb_unlocked_cache_return_entry_r( c, e ) bdb_cache_return_entry_rw((c), (e), 0)
|
||||
#define bdb_unlocked_cache_return_entry_w( c, e ) bdb_cache_return_entry_rw((c), (e), 1)
|
||||
int bdb_cache_add_entry_rw(
|
||||
Cache *cache,
|
||||
Entry *e,
|
||||
int rw
|
||||
DB_ENV *env,
|
||||
Cache *cache,
|
||||
Entry *e,
|
||||
int rw,
|
||||
u_int32_t locker,
|
||||
DB_LOCK *lock
|
||||
);
|
||||
int bdb_cache_update_entry(
|
||||
Cache *cache,
|
||||
@ -319,9 +327,12 @@ ID bdb_cache_find_entry_ndn2id(
|
||||
struct berval *ndn
|
||||
);
|
||||
Entry* bdb_cache_find_entry_id(
|
||||
Cache *cache,
|
||||
ID id,
|
||||
int rw
|
||||
DB_ENV *env,
|
||||
Cache *cache,
|
||||
ID id,
|
||||
int rw,
|
||||
u_int32_t locker,
|
||||
DB_LOCK *lock
|
||||
);
|
||||
int bdb_cache_delete_entry(
|
||||
Cache *cache,
|
||||
|
@ -26,6 +26,9 @@ bdb_referrals(
|
||||
Entry *e = NULL;
|
||||
Entry *matched = NULL;
|
||||
|
||||
u_int32_t locker;
|
||||
DB_LOCK lock;
|
||||
|
||||
if( op->o_tag == LDAP_REQ_SEARCH ) {
|
||||
/* let search take care of itself */
|
||||
return rc;
|
||||
@ -36,8 +39,11 @@ bdb_referrals(
|
||||
return rc;
|
||||
}
|
||||
|
||||
LOCK_ID ( bdb->bi_dbenv, &locker );
|
||||
|
||||
dn2entry_retry:
|
||||
/* get entry */
|
||||
rc = bdb_dn2entry_r( be, NULL, ndn, &e, &matched, 0 );
|
||||
rc = bdb_dn2entry_r( be, NULL, ndn, &e, &matched, 0, locker, &lock );
|
||||
|
||||
switch(rc) {
|
||||
case DB_NOTFOUND:
|
||||
@ -46,14 +52,18 @@ bdb_referrals(
|
||||
break;
|
||||
case LDAP_BUSY:
|
||||
if (e != NULL) {
|
||||
bdb_cache_return_entry_r(&bdb->bi_cache, e);
|
||||
bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache, e, &lock);
|
||||
}
|
||||
if (matched != NULL) {
|
||||
bdb_cache_return_entry_r(&bdb->bi_cache, matched);
|
||||
bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache, matched, &lock);
|
||||
}
|
||||
send_ldap_result( conn, op, LDAP_BUSY,
|
||||
NULL, "ldap server busy", NULL, NULL );
|
||||
LOCK_ID_FREE ( bdb->bi_dbenv, locker );
|
||||
return LDAP_BUSY;
|
||||
case DB_LOCK_DEADLOCK:
|
||||
case DB_LOCK_NOTGRANTED:
|
||||
goto dn2entry_retry;
|
||||
default:
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG (( "referral", LDAP_LEVEL_ERR,
|
||||
@ -65,13 +75,14 @@ bdb_referrals(
|
||||
db_strerror(rc), rc, 0 );
|
||||
#endif
|
||||
if (e != NULL) {
|
||||
bdb_cache_return_entry_r(&bdb->bi_cache, e);
|
||||
bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache, e, &lock);
|
||||
}
|
||||
if (matched != NULL) {
|
||||
bdb_cache_return_entry_r(&bdb->bi_cache, matched);
|
||||
bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache, matched, &lock);
|
||||
}
|
||||
send_ldap_result( conn, op, rc=LDAP_OTHER,
|
||||
NULL, "internal error", NULL, NULL );
|
||||
LOCK_ID_FREE ( bdb->bi_dbenv, locker );
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -97,7 +108,7 @@ bdb_referrals(
|
||||
refs = get_entry_referrals( be, conn, op, matched );
|
||||
}
|
||||
|
||||
bdb_cache_return_entry_r (&bdb->bi_cache, matched);
|
||||
bdb_cache_return_entry_r (bdb->bi_dbenv, &bdb->bi_cache, matched, &lock);
|
||||
matched = NULL;
|
||||
} else if ( default_referral != NULL ) {
|
||||
rc = LDAP_OTHER;
|
||||
@ -116,6 +127,7 @@ bdb_referrals(
|
||||
NULL, NULL );
|
||||
}
|
||||
|
||||
LOCK_ID_FREE ( bdb->bi_dbenv, locker );
|
||||
free( matched_dn );
|
||||
return rc;
|
||||
}
|
||||
@ -148,6 +160,7 @@ bdb_referrals(
|
||||
ber_bvarray_free( refs );
|
||||
}
|
||||
|
||||
bdb_cache_return_entry_r(&bdb->bi_cache, e);
|
||||
bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache, e, &lock);
|
||||
LOCK_ID_FREE ( bdb->bi_dbenv, locker );
|
||||
return rc;
|
||||
}
|
||||
|
@ -59,6 +59,9 @@ bdb_search(
|
||||
struct slap_limits_set *limit = NULL;
|
||||
int isroot = 0;
|
||||
|
||||
u_int32_t locker;
|
||||
DB_LOCK lock;
|
||||
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG (( "search", LDAP_LEVEL_ENTRY,"bdb_back_search\n"));
|
||||
#else
|
||||
@ -68,6 +71,8 @@ bdb_search(
|
||||
|
||||
manageDSAit = get_manageDSAit( op );
|
||||
|
||||
LOCK_ID (bdb->bi_dbenv, &locker );
|
||||
|
||||
if ( nbase->bv_len == 0 ) {
|
||||
/* DIT root special case */
|
||||
e = (Entry *) &slap_entry_root;
|
||||
@ -81,7 +86,8 @@ bdb_search(
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
rc = bdb_dn2entry_r( be, NULL, nbase, &e, &matched, 0 );
|
||||
dn2entry_retry:
|
||||
rc = bdb_dn2entry_r( be, NULL, nbase, &e, &matched, 0, locker, &lock );
|
||||
}
|
||||
|
||||
switch(rc) {
|
||||
@ -90,23 +96,28 @@ bdb_search(
|
||||
break;
|
||||
case LDAP_BUSY:
|
||||
if (e != NULL) {
|
||||
bdb_cache_return_entry_r(&bdb->bi_cache, e);
|
||||
bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache, e, &lock);
|
||||
}
|
||||
if (matched != NULL) {
|
||||
bdb_cache_return_entry_r(&bdb->bi_cache, matched);
|
||||
bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache, matched, &lock);
|
||||
}
|
||||
send_ldap_result( conn, op, LDAP_BUSY,
|
||||
NULL, "ldap server busy", NULL, NULL );
|
||||
LOCK_ID_FREE (bdb->bi_dbenv, locker );
|
||||
return LDAP_BUSY;
|
||||
case DB_LOCK_DEADLOCK:
|
||||
case DB_LOCK_NOTGRANTED:
|
||||
goto dn2entry_retry;
|
||||
default:
|
||||
if (e != NULL) {
|
||||
bdb_cache_return_entry_r(&bdb->bi_cache, e);
|
||||
bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache, e, &lock);
|
||||
}
|
||||
if (matched != NULL) {
|
||||
bdb_cache_return_entry_r(&bdb->bi_cache, matched);
|
||||
bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache, matched, &lock);
|
||||
}
|
||||
send_ldap_result( conn, op, rc=LDAP_OTHER,
|
||||
NULL, "internal error", NULL, NULL );
|
||||
LOCK_ID_FREE (bdb->bi_dbenv, locker );
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -123,7 +134,7 @@ bdb_search(
|
||||
? get_entry_referrals( be, conn, op, matched )
|
||||
: NULL;
|
||||
|
||||
bdb_cache_return_entry_r (&bdb->bi_cache, matched);
|
||||
bdb_cache_return_entry_r (bdb->bi_dbenv, &bdb->bi_cache, matched, &lock);
|
||||
matched = NULL;
|
||||
|
||||
if( erefs ) {
|
||||
@ -140,6 +151,7 @@ bdb_search(
|
||||
send_ldap_result( conn, op, rc=LDAP_REFERRAL ,
|
||||
matched_dn.bv_val, text, refs, NULL );
|
||||
|
||||
LOCK_ID_FREE (bdb->bi_dbenv, locker );
|
||||
if ( refs ) ber_bvarray_free( refs );
|
||||
if ( matched_dn.bv_val ) ber_memfree( matched_dn.bv_val );
|
||||
return rc;
|
||||
@ -154,7 +166,7 @@ bdb_search(
|
||||
erefs = get_entry_referrals( be, conn, op, e );
|
||||
refs = NULL;
|
||||
|
||||
bdb_cache_return_entry_r( &bdb->bi_cache, e );
|
||||
bdb_cache_return_entry_r( bdb->bi_dbenv, &bdb->bi_cache, e, &lock );
|
||||
e = NULL;
|
||||
|
||||
if( erefs ) {
|
||||
@ -175,6 +187,7 @@ bdb_search(
|
||||
refs ? NULL : "bad referral object",
|
||||
refs, NULL );
|
||||
|
||||
LOCK_ID_FREE (bdb->bi_dbenv, locker );
|
||||
ber_bvarray_free( refs );
|
||||
ber_memfree( matched_dn.bv_val );
|
||||
return 1;
|
||||
@ -270,7 +283,7 @@ bdb_search(
|
||||
cursor = e->e_id == NOID ? 1 : e->e_id;
|
||||
|
||||
if ( e != &slap_entry_root ) {
|
||||
bdb_cache_return_entry_r(&bdb->bi_cache, e);
|
||||
bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache, e, &lock);
|
||||
}
|
||||
e = NULL;
|
||||
|
||||
@ -320,14 +333,18 @@ bdb_search(
|
||||
goto done;
|
||||
}
|
||||
|
||||
id2entry_retry:
|
||||
/* get the entry with reader lock */
|
||||
rc = bdb_id2entry_r( be, NULL, id, &e );
|
||||
rc = bdb_id2entry_r( be, NULL, id, &e, locker, &lock );
|
||||
|
||||
if (rc == LDAP_BUSY) {
|
||||
send_ldap_result( conn, op, rc=LDAP_BUSY,
|
||||
NULL, "ldap server busy", NULL, NULL );
|
||||
goto done;
|
||||
}
|
||||
else if ( rc == DB_LOCK_DEADLOCK || rc == DB_LOCK_NOTGRANTED ) {
|
||||
goto id2entry_retry;
|
||||
}
|
||||
|
||||
if ( e == NULL ) {
|
||||
if( !BDB_IDL_IS_RANGE(candidates) ) {
|
||||
@ -456,7 +473,7 @@ bdb_search(
|
||||
if ( scopeok ) {
|
||||
/* check size limit */
|
||||
if ( --slimit == -1 ) {
|
||||
bdb_cache_return_entry_r (&bdb->bi_cache, e);
|
||||
bdb_cache_return_entry_r (bdb->bi_dbenv, &bdb->bi_cache, e, &lock);
|
||||
e = NULL;
|
||||
send_search_result( conn, op,
|
||||
rc = LDAP_SIZELIMIT_EXCEEDED, NULL, NULL,
|
||||
@ -481,7 +498,7 @@ bdb_search(
|
||||
case 1: /* entry not sent */
|
||||
break;
|
||||
case -1: /* connection closed */
|
||||
bdb_cache_return_entry_r(&bdb->bi_cache, e);
|
||||
bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache, e, &lock);
|
||||
e = NULL;
|
||||
rc = LDAP_OTHER;
|
||||
goto done;
|
||||
@ -509,7 +526,7 @@ bdb_search(
|
||||
loop_continue:
|
||||
if( e != NULL ) {
|
||||
/* free reader lock */
|
||||
bdb_cache_return_entry_r ( &bdb->bi_cache, e );
|
||||
bdb_cache_return_entry_r ( bdb->bi_dbenv, &bdb->bi_cache, e , &lock);
|
||||
e = NULL;
|
||||
}
|
||||
|
||||
@ -524,9 +541,11 @@ loop_continue:
|
||||
done:
|
||||
if( e != NULL ) {
|
||||
/* free reader lock */
|
||||
bdb_cache_return_entry_r ( &bdb->bi_cache, e );
|
||||
bdb_cache_return_entry_r ( bdb->bi_dbenv, &bdb->bi_cache, e, &lock );
|
||||
}
|
||||
|
||||
LOCK_ID_FREE (bdb->bi_dbenv, locker );
|
||||
|
||||
if( v2refs ) ber_bvarray_free( v2refs );
|
||||
if( realbase.bv_val ) ch_free( realbase.bv_val );
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user