mirror of
https://git.openldap.org/openldap/openldap.git
synced 2024-12-21 03:10:25 +08:00
Fix attribute/group to allow TXN to abort on lock failure. Save and
restore op->o_do_not_cache on TXN retry, bdb_group will set it if it fails to get a lock.
This commit is contained in:
parent
00837465c4
commit
18554e7511
@ -99,6 +99,7 @@ retry: /* transaction retry */
|
|||||||
rc = TXN_ABORT( ltid );
|
rc = TXN_ABORT( ltid );
|
||||||
ltid = NULL;
|
ltid = NULL;
|
||||||
op->o_private = NULL;
|
op->o_private = NULL;
|
||||||
|
op->o_do_not_cache = opinfo.boi_acl_cache;
|
||||||
if( rc != 0 ) {
|
if( rc != 0 ) {
|
||||||
rc = LDAP_OTHER;
|
rc = LDAP_OTHER;
|
||||||
text = "internal error";
|
text = "internal error";
|
||||||
@ -134,6 +135,7 @@ retry: /* transaction retry */
|
|||||||
opinfo.boi_txn = ltid;
|
opinfo.boi_txn = ltid;
|
||||||
opinfo.boi_locker = locker;
|
opinfo.boi_locker = locker;
|
||||||
opinfo.boi_err = 0;
|
opinfo.boi_err = 0;
|
||||||
|
opinfo.boi_acl_cache = op->o_do_not_cache;
|
||||||
op->o_private = &opinfo;
|
op->o_private = &opinfo;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -104,6 +104,12 @@ dn2entry_retry:
|
|||||||
break;
|
break;
|
||||||
case DB_LOCK_DEADLOCK:
|
case DB_LOCK_DEADLOCK:
|
||||||
case DB_LOCK_NOTGRANTED:
|
case DB_LOCK_NOTGRANTED:
|
||||||
|
/* the txn must abort and retry */
|
||||||
|
if ( txn ) {
|
||||||
|
boi->boi_err = rc;
|
||||||
|
return LDAP_BUSY;
|
||||||
|
}
|
||||||
|
ldap_pvt_thread_yield();
|
||||||
goto dn2entry_retry;
|
goto dn2entry_retry;
|
||||||
default:
|
default:
|
||||||
boi->boi_err = rc;
|
boi->boi_err = rc;
|
||||||
|
@ -157,6 +157,7 @@ struct bdb_op_info {
|
|||||||
DB_TXN* boi_txn;
|
DB_TXN* boi_txn;
|
||||||
u_int32_t boi_err;
|
u_int32_t boi_err;
|
||||||
u_int32_t boi_locker;
|
u_int32_t boi_locker;
|
||||||
|
int boi_acl_cache;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define DB_OPEN(db, file, name, type, flags, mode) \
|
#define DB_OPEN(db, file, name, type, flags, mode) \
|
||||||
|
@ -70,6 +70,7 @@ retry: /* transaction retry */
|
|||||||
rc = TXN_ABORT( ltid );
|
rc = TXN_ABORT( ltid );
|
||||||
ltid = NULL;
|
ltid = NULL;
|
||||||
op->o_private = NULL;
|
op->o_private = NULL;
|
||||||
|
op->o_do_not_cache = opinfo.boi_acl_cache;
|
||||||
if( rc != 0 ) {
|
if( rc != 0 ) {
|
||||||
rc = LDAP_OTHER;
|
rc = LDAP_OTHER;
|
||||||
text = "internal error";
|
text = "internal error";
|
||||||
@ -106,6 +107,7 @@ retry: /* transaction retry */
|
|||||||
opinfo.boi_txn = ltid;
|
opinfo.boi_txn = ltid;
|
||||||
opinfo.boi_locker = locker;
|
opinfo.boi_locker = locker;
|
||||||
opinfo.boi_err = 0;
|
opinfo.boi_err = 0;
|
||||||
|
opinfo.boi_acl_cache = op->o_do_not_cache;
|
||||||
op->o_private = &opinfo;
|
op->o_private = &opinfo;
|
||||||
|
|
||||||
if ( !be_issuffix( be, ndn ) ) {
|
if ( !be_issuffix( be, ndn ) ) {
|
||||||
|
@ -109,9 +109,19 @@ dn2entry_retry:
|
|||||||
/* can we find group entry */
|
/* can we find group entry */
|
||||||
rc = bdb_dn2entry_r( be, txn, gr_ndn, &e, NULL, 0, locker, &lock );
|
rc = bdb_dn2entry_r( be, txn, gr_ndn, &e, NULL, 0, locker, &lock );
|
||||||
if( rc ) {
|
if( rc ) {
|
||||||
if ( rc == DB_LOCK_DEADLOCK || rc == DB_LOCK_NOTGRANTED )
|
|
||||||
goto dn2entry_retry;
|
|
||||||
boi->boi_err = rc;
|
boi->boi_err = rc;
|
||||||
|
if ( rc == DB_LOCK_DEADLOCK || rc == DB_LOCK_NOTGRANTED ) {
|
||||||
|
if ( txn ) {
|
||||||
|
/* must let owning txn abort, but our result
|
||||||
|
* is still inconclusive, so don't let it
|
||||||
|
* get cached.
|
||||||
|
*/
|
||||||
|
op->o_do_not_cache = 1;
|
||||||
|
return( 1 );
|
||||||
|
}
|
||||||
|
ldap_pvt_thread_yield();
|
||||||
|
goto dn2entry_retry;
|
||||||
|
}
|
||||||
if ( free_lock_id ) {
|
if ( free_lock_id ) {
|
||||||
LOCK_ID_FREE ( bdb->bi_dbenv, locker );
|
LOCK_ID_FREE ( bdb->bi_dbenv, locker );
|
||||||
}
|
}
|
||||||
|
@ -319,6 +319,7 @@ retry: /* transaction retry */
|
|||||||
rc = TXN_ABORT( ltid );
|
rc = TXN_ABORT( ltid );
|
||||||
ltid = NULL;
|
ltid = NULL;
|
||||||
op->o_private = NULL;
|
op->o_private = NULL;
|
||||||
|
op->o_do_not_cache = opinfo.boi_acl_cache;
|
||||||
if( rc != 0 ) {
|
if( rc != 0 ) {
|
||||||
rc = LDAP_OTHER;
|
rc = LDAP_OTHER;
|
||||||
text = "internal error";
|
text = "internal error";
|
||||||
@ -351,6 +352,7 @@ retry: /* transaction retry */
|
|||||||
opinfo.boi_txn = ltid;
|
opinfo.boi_txn = ltid;
|
||||||
opinfo.boi_locker = locker;
|
opinfo.boi_locker = locker;
|
||||||
opinfo.boi_err = 0;
|
opinfo.boi_err = 0;
|
||||||
|
opinfo.boi_acl_cache = op->o_do_not_cache;
|
||||||
op->o_private = &opinfo;
|
op->o_private = &opinfo;
|
||||||
|
|
||||||
/* get entry */
|
/* get entry */
|
||||||
|
@ -108,6 +108,7 @@ retry: /* transaction retry */
|
|||||||
rc = TXN_ABORT( ltid );
|
rc = TXN_ABORT( ltid );
|
||||||
ltid = NULL;
|
ltid = NULL;
|
||||||
op->o_private = NULL;
|
op->o_private = NULL;
|
||||||
|
op->o_do_not_cache = opinfo.boi_acl_cache;
|
||||||
if( rc != 0 ) {
|
if( rc != 0 ) {
|
||||||
rc = LDAP_OTHER;
|
rc = LDAP_OTHER;
|
||||||
text = "internal error";
|
text = "internal error";
|
||||||
@ -141,6 +142,7 @@ retry: /* transaction retry */
|
|||||||
opinfo.boi_txn = ltid;
|
opinfo.boi_txn = ltid;
|
||||||
opinfo.boi_locker = locker;
|
opinfo.boi_locker = locker;
|
||||||
opinfo.boi_err = 0;
|
opinfo.boi_err = 0;
|
||||||
|
opinfo.boi_acl_cache = op->o_do_not_cache;
|
||||||
op->o_private = &opinfo;
|
op->o_private = &opinfo;
|
||||||
|
|
||||||
/* get entry */
|
/* get entry */
|
||||||
@ -276,6 +278,12 @@ retry: /* transaction retry */
|
|||||||
rc = access_allowed( be, conn, op, p,
|
rc = access_allowed( be, conn, op, p,
|
||||||
children, NULL, ACL_WRITE, NULL );
|
children, NULL, ACL_WRITE, NULL );
|
||||||
|
|
||||||
|
switch( opinfo.boi_err ) {
|
||||||
|
case DB_LOCK_DEADLOCK:
|
||||||
|
case DB_LOCK_NOTGRANTED:
|
||||||
|
goto retry;
|
||||||
|
}
|
||||||
|
|
||||||
if ( ! rc ) {
|
if ( ! rc ) {
|
||||||
rc = LDAP_INSUFFICIENT_ACCESS;
|
rc = LDAP_INSUFFICIENT_ACCESS;
|
||||||
#ifdef NEW_LOGGING
|
#ifdef NEW_LOGGING
|
||||||
@ -326,6 +334,12 @@ retry: /* transaction retry */
|
|||||||
rc = access_allowed( be, conn, op, p,
|
rc = access_allowed( be, conn, op, p,
|
||||||
children, NULL, ACL_WRITE, NULL );
|
children, NULL, ACL_WRITE, NULL );
|
||||||
|
|
||||||
|
switch( opinfo.boi_err ) {
|
||||||
|
case DB_LOCK_DEADLOCK:
|
||||||
|
case DB_LOCK_NOTGRANTED:
|
||||||
|
goto retry;
|
||||||
|
}
|
||||||
|
|
||||||
p = NULL;
|
p = NULL;
|
||||||
|
|
||||||
if ( ! rc ) {
|
if ( ! rc ) {
|
||||||
@ -467,6 +481,12 @@ retry: /* transaction retry */
|
|||||||
rc = access_allowed( be, conn, op, np, children,
|
rc = access_allowed( be, conn, op, np, children,
|
||||||
NULL, ACL_WRITE, NULL );
|
NULL, ACL_WRITE, NULL );
|
||||||
|
|
||||||
|
switch( opinfo.boi_err ) {
|
||||||
|
case DB_LOCK_DEADLOCK:
|
||||||
|
case DB_LOCK_NOTGRANTED:
|
||||||
|
goto retry;
|
||||||
|
}
|
||||||
|
|
||||||
if( ! rc ) {
|
if( ! rc ) {
|
||||||
#ifdef NEW_LOGGING
|
#ifdef NEW_LOGGING
|
||||||
LDAP_LOG ( OPERATION, DETAIL1,
|
LDAP_LOG ( OPERATION, DETAIL1,
|
||||||
@ -528,6 +548,12 @@ retry: /* transaction retry */
|
|||||||
rc = access_allowed( be, conn, op, np,
|
rc = access_allowed( be, conn, op, np,
|
||||||
children, NULL, ACL_WRITE, NULL );
|
children, NULL, ACL_WRITE, NULL );
|
||||||
|
|
||||||
|
switch( opinfo.boi_err ) {
|
||||||
|
case DB_LOCK_DEADLOCK:
|
||||||
|
case DB_LOCK_NOTGRANTED:
|
||||||
|
goto retry;
|
||||||
|
}
|
||||||
|
|
||||||
np = NULL;
|
np = NULL;
|
||||||
|
|
||||||
if ( ! rc ) {
|
if ( ! rc ) {
|
||||||
|
@ -123,6 +123,7 @@ retry: /* transaction retry */
|
|||||||
rc = TXN_ABORT( ltid );
|
rc = TXN_ABORT( ltid );
|
||||||
ltid = NULL;
|
ltid = NULL;
|
||||||
op->o_private = NULL;
|
op->o_private = NULL;
|
||||||
|
op->o_do_not_cache = opinfo.boi_acl_cache;
|
||||||
if( rc != 0 ) {
|
if( rc != 0 ) {
|
||||||
rc = LDAP_OTHER;
|
rc = LDAP_OTHER;
|
||||||
*text = "internal error";
|
*text = "internal error";
|
||||||
@ -156,6 +157,7 @@ retry: /* transaction retry */
|
|||||||
opinfo.boi_txn = ltid;
|
opinfo.boi_txn = ltid;
|
||||||
opinfo.boi_locker = locker;
|
opinfo.boi_locker = locker;
|
||||||
opinfo.boi_err = 0;
|
opinfo.boi_err = 0;
|
||||||
|
opinfo.boi_acl_cache = op->o_do_not_cache;
|
||||||
op->o_private = &opinfo;
|
op->o_private = &opinfo;
|
||||||
|
|
||||||
/* get entry */
|
/* get entry */
|
||||||
|
Loading…
Reference in New Issue
Block a user