]> git.sur5r.net Git - openldap/commitdiff
Changes from HEAD, namely back-bdb updates
authorKurt Zeilenga <kurt@openldap.org>
Fri, 16 Jul 2004 21:51:42 +0000 (21:51 +0000)
committerKurt Zeilenga <kurt@openldap.org>
Fri, 16 Jul 2004 21:51:42 +0000 (21:51 +0000)
but also SASL, DN, matchedValues, and misc other fixes

20 files changed:
CHANGES
libraries/libldap/cyrus.c
libraries/libldap/getdn.c
libraries/libldap/options.c
libraries/libldap_r/rdwr.c
servers/slapd/back-bdb/back-bdb.h
servers/slapd/back-bdb/cache.c
servers/slapd/back-bdb/config.c
servers/slapd/back-bdb/ctxcsn.c
servers/slapd/back-bdb/dn2id.c
servers/slapd/back-bdb/id2entry.c
servers/slapd/back-bdb/idl.c
servers/slapd/back-bdb/init.c
servers/slapd/back-bdb/modify.c
servers/slapd/back-bdb/modrdn.c
servers/slapd/back-bdb/operational.c
servers/slapd/back-bdb/proto-bdb.h
servers/slapd/back-bdb/search.c
servers/slapd/ctxcsn.c
servers/slapd/matchedValues.c

diff --git a/CHANGES b/CHANGES
index a5a6d2abbb2c906e41d5b47219674a2820bd46e2..9d1d0482bbd02f994d01ac2a88e97bd25867b034 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -6,15 +6,20 @@ OpenLDAP 2.2.15 Engineering
        Fixed back-bdb ctxcsn locking bug
        Fixed back-ldap validate/pretty values (ITS#3218)
        Fixed back-ldap shared connections failover (ITS#3217)
+       Fixed slapi slapi_int_compute_output_ber attrs bug
        Fixed slapd oidValidate 0 bug (ITS#3211)
        Fixed slapd uniqueMember/nameUID bugs (ITS#3210)
        Fixed slapd operational attribute log message bug (ITS#3205)
        Fixed slapd invalid cookie in pagedResults control (ITS#3089)
        Fixed slapd group ACL locking bug (ITS#3173)
-       Fixed slapi slapi_int_compute_output_ber attrs bug
+       Fixed slapd abandon/cancel pending bug
+       Fixed slapd attribute description syntax bug
+       Fixed libldap SASL re-encode bug
        Fixed libldap sasl_encode 64-bit bug (ITS#3054,3212)
        Fixed libldap matchedValues parsing bug (ITS#3208,3216)
+       Fixed libldap DN '=' handling
        Fixed libldap_r runqueue bug
+       Updated libldap_r read/writer locks
        Build environments
                Added additional res_query detection for MacOS X
                Added default ldapi:// SSF build setting
index 2c55ce0d21f2936309bdb3e79d988c3c8c91eb9a..3eb84808459cd9e0740bcf6f67443bfebcbd885e 100644 (file)
@@ -347,12 +347,12 @@ sb_sasl_write( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len)
        /* Are there anything left in the buffer? */
        if ( p->buf_out.buf_ptr != p->buf_out.buf_end ) {
                ret = ber_pvt_sb_do_write( sbiod, &p->buf_out );
-               if ( ret < 0 )
-                       return ret;
+               if ( ret < 0 ) return ret;
+
                /* Still have something left?? */
                if ( p->buf_out.buf_ptr != p->buf_out.buf_end ) {
                        errno = EAGAIN;
-                       return 0;
+                       return -1;
                }
        }
 
@@ -378,16 +378,16 @@ sb_sasl_write( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len)
                ber_log_printf( LDAP_DEBUG_ANY, sbiod->sbiod_sb->sb_debug,
                        "sb_sasl_write: failed to encode packet: %s\n",
                        sasl_errstring( ret, NULL, NULL ) );
+               errno = EIO;
                return -1;
        }
        p->buf_out.buf_end = p->buf_out.buf_size;
 
        ret = ber_pvt_sb_do_write( sbiod, &p->buf_out );
-       if ( ret <= 0 ) {
-               /* caller will retry, so clear this buffer out */
-               p->buf_out.buf_ptr = p->buf_out.buf_end;
-               return ret;
-       }
+
+       /* return number of bytes encoded, not written, to ensure
+        * no byte is encoded twice (even if only sent once).
+        */
        return len;
 }
 
@@ -399,8 +399,7 @@ sb_sasl_ctrl( Sockbuf_IO_Desc *sbiod, int opt, void *arg )
        p = (struct sb_sasl_data *)sbiod->sbiod_pvt;
 
        if ( opt == LBER_SB_OPT_DATA_READY ) {
-               if ( p->buf_in.buf_ptr != p->buf_in.buf_end )
-                       return 1;
+               if ( p->buf_in.buf_ptr != p->buf_in.buf_end ) return 1;
        }
        
        return LBER_SBIOD_CTRL_NEXT( sbiod, opt, arg );
index af3b8f0da8a4c57ad3ee3017ab60fbeb3efeeff8..0f68bfdc76325c94910ce1bc76e9589927979e96 100644 (file)
@@ -469,6 +469,26 @@ ldap_dn_normalize( LDAP_CONST char *dnin,
 #define LDAP_DN_ESCAPE(c)              ( (c) == '\\' )
 #define LDAP_DN_VALUE_END(c) \
        ( LDAP_DN_RDN_SEP(c) || LDAP_DN_AVA_SEP(c) )
+
+/* NOTE: according to draft-ietf-ldapbis-dn, '=' can be escaped
+ * and treated as special, i.e. escaped both as "\<hexpair>" and
+ * as "\=", but it is treated as a regular char, i.e. it can also 
+ * appear as '='.
+ *
+ * As such, we currently choose to allow reading unescaped '=',
+ * but we always produce escaped '\3D'; this may change in the
+ * future, if compatibility issues do not arise */
+#ifdef LDAP_DEVEL
+#define LDAP_DN_NE(c) \
+       ( LDAP_DN_RDN_SEP_V2(c) || LDAP_DN_AVA_SEP(c) \
+         || LDAP_DN_QUOTES(c) \
+         || (c) == '<' || (c) == '>' )
+#define LDAP_DN_MAYESCAPE(c) \
+       ( LDAP_DN_ESCAPE(c) || LDAP_DN_NE(c) \
+         || LDAP_DN_AVA_EQUALS(c) \
+         || LDAP_DN_ASCII_SPACE(c) || LDAP_DN_OCTOTHORPE(c) )
+#define LDAP_DN_SHOULDESCAPE(c)                ( LDAP_DN_AVA_EQUALS(c) )
+#else /* ! LDAP_DEVEL */
 #define LDAP_DN_NE(c) \
        ( LDAP_DN_RDN_SEP_V2(c) || LDAP_DN_AVA_SEP(c) \
          || LDAP_DN_AVA_EQUALS(c) || LDAP_DN_QUOTES(c) \
@@ -476,6 +496,9 @@ ldap_dn_normalize( LDAP_CONST char *dnin,
 #define LDAP_DN_MAYESCAPE(c) \
        ( LDAP_DN_ESCAPE(c) || LDAP_DN_NE(c) \
          || LDAP_DN_ASCII_SPACE(c) || LDAP_DN_OCTOTHORPE(c) )
+#define LDAP_DN_SHOULDESCAPE(c)                ( 0 )
+#endif /* ! LDAP_DEVEL */
+       
 #define LDAP_DN_NEEDESCAPE(c) \
        ( LDAP_DN_ESCAPE(c) || LDAP_DN_NE(c) )
 #define LDAP_DN_NEEDESCAPE_LEAD(c)     LDAP_DN_MAYESCAPE(c)
@@ -730,9 +753,9 @@ ldap_bv2dn_x( struct berval *bv, LDAPDN *dn, unsigned flags, void *ctx )
        assert( dn );
 
 #ifdef NEW_LOGGING
-       LDAP_LOG ( OPERATION, ARGS, "ldap_bv2dn(%s,%u)\n%s", str, flags, "" );
+       LDAP_LOG ( OPERATION, ARGS, "ldap_bv2dn(%s,%u)\n", str, flags, 0 );
 #else
-       Debug( LDAP_DEBUG_TRACE, "=> ldap_bv2dn(%s,%u)\n%s", str, flags, "" );
+       Debug( LDAP_DEBUG_TRACE, "=> ldap_bv2dn(%s,%u)\n", str, flags, 0 );
 #endif
 
        *dn = NULL;
@@ -903,10 +926,11 @@ return_result:;
        }
 
 #ifdef NEW_LOGGING
-       LDAP_LOG ( OPERATION, RESULTS, "<= ldap_bv2dn(%s,%u)=%d\n", 
-               str, flags, rc );
+       LDAP_LOG ( OPERATION, RESULTS, "<= ldap_bv2dn(%s)=%d %s\n", 
+               str, rc, ldap_err2string( rc ) );
 #else
-       Debug( LDAP_DEBUG_TRACE, "<= ldap_bv2dn(%s,%u)=%d\n", str, flags, rc );
+       Debug( LDAP_DEBUG_TRACE, "<= ldap_bv2dn(%s)=%d %s\n", str, rc,
+                       ldap_err2string( rc ) );
 #endif
        *dn = newDN;
        
@@ -1497,7 +1521,7 @@ str2strval( const char *str, ber_len_t stoplen, struct berval *val, const char *
                         */
                        return( 1 );
 
-               } else if (!LDAP_DN_ASCII_PRINTABLE( p[ 0 ] ) ) {
+               } else if ( !LDAP_DN_ASCII_PRINTABLE( p[ 0 ] ) ) {
                        if ( p[ 0 ] == '\0' ) {
                                return( 1 );
                        }
@@ -2082,6 +2106,7 @@ strval2strlen( struct berval *val, unsigned flags, ber_len_t *len )
                        l += escaped_byte_len * cl;
 
                } else if ( LDAP_DN_NEEDESCAPE( p[ 0 ] )
+                               || LDAP_DN_SHOULDESCAPE( p[ 0 ] )
                                || ( p == val->bv_val && LDAP_DN_NEEDESCAPE_LEAD( p[ 0 ] ) )
                                || ( !p[ 1 ] && LDAP_DN_NEEDESCAPE_TRAIL( p[ 0 ] ) ) ) {
 #ifdef PRETTY_ESCAPE
@@ -2172,6 +2197,7 @@ strval2str( struct berval *val, char *str, unsigned flags, ber_len_t *len )
 #endif
 #else /* ! PRETTY_ESCAPE */
                                || LDAP_DN_NEEDESCAPE( val->bv_val[ s ] )
+                               || LDAP_DN_SHOULDESCAPE( val->bv_val[ s ] )
                                || ( d == 0 && LDAP_DN_NEEDESCAPE_LEAD( val->bv_val[ s ] ) )
                                || ( s == end && LDAP_DN_NEEDESCAPE_TRAIL( val->bv_val[ s ] ) )
 
@@ -2192,6 +2218,7 @@ strval2str( struct berval *val, char *str, unsigned flags, ber_len_t *len )
                } else {
 #ifdef PRETTY_ESCAPE
                        if ( LDAP_DN_NEEDESCAPE( val->bv_val[ s ] )
+                                       || LDAP_DN_SHOULDESCAPE( val->bv_val[ s ] )
                                        || ( d == 0 && LDAP_DN_NEEDESCAPE_LEAD( val->bv_val[ s ] ) )
                                        || ( s == end && LDAP_DN_NEEDESCAPE_TRAIL( val->bv_val[ s ] ) ) ) {
                                str[ d++ ] = '\\';
@@ -2238,6 +2265,7 @@ strval2IA5strlen( struct berval *val, unsigned flags, ber_len_t *len )
        } else {
                for ( l = 0, p = val->bv_val; p[ 0 ]; p++ ) {
                        if ( LDAP_DN_NEEDESCAPE( p[ 0 ] )
+                                       || LDAP_DN_SHOULDESCAPE( p[ 0 ] )
                                        || ( p == val->bv_val && LDAP_DN_NEEDESCAPE_LEAD( p[ 0 ] ) )
                                        || ( !p[ 1 ] && LDAP_DN_NEEDESCAPE_TRAIL( p[ 0 ] ) ) ) {
                                l += 2;
@@ -2286,6 +2314,7 @@ strval2IA5str( struct berval *val, char *str, unsigned flags, ber_len_t *len )
 
                for ( s = 0, d = 0, end = val->bv_len - 1; s < val->bv_len; ) {
                        if ( LDAP_DN_NEEDESCAPE( val->bv_val[ s ] )
+                                       || LDAP_DN_SHOULDESCAPE( val->bv_val[ s ] )
                                        || ( s == 0 && LDAP_DN_NEEDESCAPE_LEAD( val->bv_val[ s ] ) )
                                        || ( s == end && LDAP_DN_NEEDESCAPE_TRAIL( val->bv_val[ s ] ) ) ) {
                                str[ d++ ] = '\\';
@@ -3013,10 +3042,9 @@ int ldap_dn2bv_x( LDAPDN dn, struct berval *bv, unsigned flags, void *ctx )
        bv->bv_val = NULL;
 
 #ifdef NEW_LOGGING
-       LDAP_LOG ( OPERATION, ARGS, "=> ldap_dn2bv(%u)\n%s%s", 
-               flags, "", "" );
+       LDAP_LOG ( OPERATION, ARGS, "=> ldap_dn2bv(%u)\n", flags, 0, 0 );
 #else
-       Debug( LDAP_DEBUG_TRACE, "=> ldap_dn2bv(%u)\n%s%s", flags, "", "" );
+       Debug( LDAP_DEBUG_TRACE, "=> ldap_dn2bv(%u)\n", flags, 0, 0 );
 #endif
 
        /* 
@@ -3327,11 +3355,11 @@ int ldap_dn2bv_x( LDAPDN dn, struct berval *bv, unsigned flags, void *ctx )
        }
 
 #ifdef NEW_LOGGING
-       LDAP_LOG ( OPERATION, RESULTS, "<= ldap_dn2bv(%s,%u)=%d\n", 
-               bv->bv_val, flags, rc );
+       LDAP_LOG ( OPERATION, RESULTS, "<= ldap_dn2bv(%s)=%d %s\n", 
+               bv->bv_val, rc, ldap_err2string( rc ) );
 #else
-       Debug( LDAP_DEBUG_TRACE, "<= ldap_dn2bv(%s,%u)=%d\n",
-               bv->bv_val, flags, rc );
+       Debug( LDAP_DEBUG_TRACE, "<= ldap_dn2bv(%s)=%d %s\n",
+               bv->bv_val, rc, ldap_err2string( rc ) );
 #endif
 
 return_results:;
index c8b2ac286a1b8bcd8a084588219ecb966cab801f..f191cb8161c4d3b34e58e5f104aee74ae392cf27 100644 (file)
@@ -529,7 +529,6 @@ ldap_set_option(
 
                        if(urls != NULL) {
                                rc = ldap_url_parselist(&ludlist, urls);
-
                        } else if(ld == NULL) {
                                /*
                                 * must want global default returned
@@ -548,6 +547,28 @@ ldap_set_option(
                                        rc = LDAP_NO_MEMORY;
                        }
 
+                       switch (rc) {
+                       case LDAP_URL_SUCCESS:          /* Success */
+                               rc = LDAP_SUCCESS;
+                               break;
+
+                       case LDAP_URL_ERR_MEM:          /* can't allocate memory space */
+                               rc = LDAP_NO_MEMORY;
+                               break;
+
+                       case LDAP_URL_ERR_PARAM:        /* parameter is bad */
+                       case LDAP_URL_ERR_BADSCHEME:    /* URL doesn't begin with "ldap[si]://" */
+                       case LDAP_URL_ERR_BADENCLOSURE: /* URL is missing trailing ">" */
+                       case LDAP_URL_ERR_BADURL:       /* URL is bad */
+                       case LDAP_URL_ERR_BADHOST:      /* host port is bad */
+                       case LDAP_URL_ERR_BADATTRS:     /* bad (or missing) attributes */
+                       case LDAP_URL_ERR_BADSCOPE:     /* scope string is invalid (or missing) */
+                       case LDAP_URL_ERR_BADFILTER:    /* bad or missing filter */
+                       case LDAP_URL_ERR_BADEXTS:      /* bad or missing extensions */
+                               rc = LDAP_PARAM_ERROR;
+                               break;
+                       }
+
                        if (rc == LDAP_OPT_SUCCESS) {
                                if (lo->ldo_defludp != NULL)
                                        ldap_free_urllist(lo->ldo_defludp);
index dc9dcedc4b4be7c53bbd3ffcb2cb4be6c6585cba..b0613c07514a0f1bca8442007bdd3fe9d40790e8 100644 (file)
@@ -59,6 +59,12 @@ struct ldap_int_thread_rdwr_s {
        int ltrw_w_active;
        int ltrw_r_wait;
        int ltrw_w_wait;
+#ifdef LDAP_RDWR_DEBUG
+       /* keep track of who has these locks */
+#define        MAX_READERS     32
+       ldap_pvt_thread_t ltrw_readers[MAX_READERS];
+       ldap_pvt_thread_t ltrw_writer;
+#endif
 };
 
 int 
@@ -162,8 +168,12 @@ int ldap_pvt_thread_rdwr_rlock( ldap_pvt_thread_rdwr_t *rwlock )
                assert( rw->ltrw_r_wait >= 0 ); 
        }
 
+#ifdef LDAP_RDWR_DEBUG
+       rw->ltrw_readers[rw->ltrw_r_active] = ldap_pvt_thread_self();
+#endif
        rw->ltrw_r_active++;
 
+
        ldap_pvt_thread_mutex_unlock( &rw->ltrw_mutex );
 
        return 0;
@@ -194,6 +204,9 @@ int ldap_pvt_thread_rdwr_rtrylock( ldap_pvt_thread_rdwr_t *rwlock )
                return LDAP_PVT_THREAD_EBUSY;
        }
 
+#ifdef LDAP_RDWR_DEBUG
+       rw->ltrw_readers[rw->ltrw_r_active] = ldap_pvt_thread_self();
+#endif
        rw->ltrw_r_active++;
 
        ldap_pvt_thread_mutex_unlock( &rw->ltrw_mutex );
@@ -216,6 +229,22 @@ int ldap_pvt_thread_rdwr_runlock( ldap_pvt_thread_rdwr_t *rwlock )
 
        ldap_pvt_thread_mutex_lock( &rw->ltrw_mutex );
 
+#ifdef LDAP_RDWR_DEBUG
+       /* Remove us from the list of readers */
+       { int i, j;
+       ldap_pvt_thread_t self = ldap_pvt_thread_self();
+
+       for (i=0; i<rw->ltrw_r_active;i++)
+       {
+               if (rw->ltrw_readers[i] == self) {
+                       for (j=i; j<rw->ltrw_r_active-1; j++)
+                               rw->ltrw_readers[j] = rw->ltrw_readers[j+1];
+                       rw->ltrw_readers[j] = 0;
+                       break;
+               }
+       }
+       }
+#endif
        rw->ltrw_r_active--;
 
        assert( rw->ltrw_w_active >= 0 ); 
@@ -264,6 +293,9 @@ int ldap_pvt_thread_rdwr_wlock( ldap_pvt_thread_rdwr_t *rwlock )
                assert( rw->ltrw_w_wait >= 0 ); 
        }
 
+#ifdef LDAP_RDWR_DEBUG
+       rw->ltrw_writer = ldap_pvt_thread_self();
+#endif
        rw->ltrw_w_active++;
 
        ldap_pvt_thread_mutex_unlock( &rw->ltrw_mutex );
@@ -296,6 +328,9 @@ int ldap_pvt_thread_rdwr_wtrylock( ldap_pvt_thread_rdwr_t *rwlock )
                return LDAP_PVT_THREAD_EBUSY;
        }
 
+#ifdef LDAP_RDWR_DEBUG
+       rw->ltrw_writer = ldap_pvt_thread_self();
+#endif
        rw->ltrw_w_active++;
 
        ldap_pvt_thread_mutex_unlock( &rw->ltrw_mutex );
@@ -332,6 +367,9 @@ int ldap_pvt_thread_rdwr_wunlock( ldap_pvt_thread_rdwr_t *rwlock )
                ldap_pvt_thread_cond_signal( &rw->ltrw_write );
        }
 
+#ifdef LDAP_RDWR_DEBUG
+       rw->ltrw_writer = 0;
+#endif
        ldap_pvt_thread_mutex_unlock( &rw->ltrw_mutex );
 
        return 0;
@@ -397,8 +435,8 @@ int ldap_pvt_thread_rdwr_active(ldap_pvt_thread_rdwr_t *rwlock)
        assert( rw->ltrw_r_active >= 0 ); 
        assert( rw->ltrw_r_wait >= 0 ); 
 
-       return(ldap_pvt_thread_rdwr_readers(rw) +
-              ldap_pvt_thread_rdwr_writers(rw));
+       return(ldap_pvt_thread_rdwr_readers(rwlock) +
+              ldap_pvt_thread_rdwr_writers(rwlock));
 }
 
 #endif /* LDAP_DEBUG */
index e3846c9b9b64acd1c4236b9019bbb6cd7bc11e96..3dcbc6de96f266f18ebfebb9183a390352419901 100644 (file)
@@ -73,10 +73,6 @@ LDAP_BEGIN_DECL
 /* The minimum we can function with */
 #define MINIMUM_SEARCH_STACK_DEPTH     8
 
-/* for the IDL cache */
-#define SLAP_IDL_CACHE 1
-
-#ifdef SLAP_IDL_CACHE
 typedef struct bdb_idl_cache_entry_s {
        struct berval kstr;
        ldap_pvt_thread_rdwr_t idl_entry_rwlock;
@@ -85,7 +81,6 @@ typedef struct bdb_idl_cache_entry_s {
        struct bdb_idl_cache_entry_s* idl_lru_prev;
        struct bdb_idl_cache_entry_s* idl_lru_next;
 } bdb_idl_cache_entry_t;
-#endif
 
 /* BDB backend specific entry info */
 typedef struct bdb_entry_info {
@@ -103,6 +98,7 @@ typedef struct bdb_entry_info {
 #define        CACHE_ENTRY_NO_KIDS     2
 #define        CACHE_ENTRY_NOT_LINKED  4
 #define CACHE_ENTRY_NO_GRANDKIDS       8
+#define        CACHE_ENTRY_LOADING     0x10
 
        /*
         * remaining fields require backend cache lock to access
@@ -180,7 +176,6 @@ struct bdb_info {
        LDAP_LIST_HEAD(pl, slap_op) bi_psearch_list;
        ldap_pvt_thread_rdwr_t bi_pslist_rwlock;
        LDAP_LIST_HEAD(se, slap_session_entry) bi_session_list;
-#ifdef SLAP_IDL_CACHE
        int             bi_idl_cache_max_size;
        int             bi_idl_cache_size;
        Avlnode         *bi_idl_tree;
@@ -188,7 +183,6 @@ struct bdb_info {
        bdb_idl_cache_entry_t   *bi_idl_lru_tail;
        ldap_pvt_thread_rdwr_t bi_idl_tree_rwlock;
        ldap_pvt_thread_mutex_t bi_idl_tree_lrulock;
-#endif
 };
 
 #define bi_id2entry    bi_databases[BDB_ID2ENTRY]
index 85d4d052d4e1654100987793919095b3e0fe6bd7..d306add2a5003f326f0a2ad43543455477a0148b 100644 (file)
@@ -31,6 +31,8 @@ static int    bdb_cache_delete_internal(Cache *cache, EntryInfo *e);
 static void    bdb_lru_print(Cache *cache);
 #endif
 
+static int bdb_txn_get( Operation *op, DB_ENV *env, DB_TXN **txn );
+
 static EntryInfo *
 bdb_cache_entryinfo_new( Cache *cache )
 {
@@ -86,7 +88,7 @@ bdb_cache_entry_db_relock(
        rc = env->lock_vec(env, locker, tryOnly ? DB_LOCK_NOWAIT : 0,
                list, 2, NULL );
 
-       if (rc) {
+       if (rc && !tryOnly) {
 #ifdef NEW_LOGGING
                LDAP_LOG( CACHE, DETAIL1, 
                        "bdb_cache_entry_db_relock: entry %ld, rw %d, rc %d\n",
@@ -126,7 +128,7 @@ bdb_cache_entry_db_lock( DB_ENV *env, u_int32_t locker, EntryInfo *ei,
 
        rc = LOCK_GET(env, locker, tryOnly ? DB_LOCK_NOWAIT : 0,
                                        &lockobj, db_rw, lock);
-       if (rc) {
+       if (rc && !tryOnly) {
 #ifdef NEW_LOGGING
                LDAP_LOG( CACHE, DETAIL1, 
                        "bdb_cache_entry_db_lock: entry %ld, rw %d, rc %d\n",
@@ -179,6 +181,7 @@ bdb_cache_entryinfo_destroy( EntryInfo *e )
        } else { \
                (cache)->c_lrutail = (ei)->bei_lruprev; \
        } \
+       (ei)->bei_lrunext = (ei)->bei_lruprev = NULL; \
 } while(0)
 
 #define LRU_ADD( cache, ei ) do { \
@@ -593,7 +596,6 @@ bdb_cache_find_id(
        Entry   *ep = NULL;
        int     rc = 0;
        EntryInfo ei;
-       int lru_del = 0;
 
        ei.bei_id = id;
 
@@ -655,40 +657,88 @@ again:    ldap_pvt_thread_rdwr_rlock( &bdb->bi_cache.c_rwlock );
                if ( (*eip)->bei_state & CACHE_ENTRY_DELETED ) {
                        rc = DB_NOTFOUND;
                } else {
-                       rc = bdb_cache_entry_db_lock( bdb->bi_dbenv, locker, *eip, 0, 0, lock );
-                       /* entry is protected now, we don't need to hold the entryinfo */
+                       int load = 0;
+                       /* Make sure only one thread tries to load the entry */
+load1:         if ( !(*eip)->bei_e && !((*eip)->bei_state & CACHE_ENTRY_LOADING)) {
+                               load = 1;
+                               (*eip)->bei_state |= CACHE_ENTRY_LOADING;
+                       }
                        if ( islocked ) {
                                bdb_cache_entryinfo_unlock( *eip );
                                islocked = 0;
                        }
-                       if ( rc == 0 ) {
-                               if ( !(*eip)->bei_e ) {
-                                       if (!ep) {
-                                               rc = bdb_id2entry( op->o_bd, tid, id, &ep );
+                       rc = bdb_cache_entry_db_lock( bdb->bi_dbenv, locker, *eip, 0, 0, lock );
+                       if ( (*eip)->bei_state & CACHE_ENTRY_DELETED ) {
+                               rc = DB_NOTFOUND;
+                               bdb_cache_entry_db_unlock( bdb->bi_dbenv, lock );
+                       } else if ( rc == 0 ) {
+                               if ( load ) {
+                                       DB_TXN *ltid;
+                                       u_int32_t locker2 = locker;
+
+                                       /* We don't wrap entire read operations in txn's, but
+                                        * we need our cache entry lock and any DB page locks
+                                        * to be associated, in order for deadlock detection
+                                        * to work properly. So if we need to read from the DB,
+                                        * we use a long-lived per-thread txn for this step.
+                                        */
+                                       if ( !ep && !tid ) {
+                                               rc = bdb_txn_get( op, bdb->bi_dbenv, &ltid );
+                                               if ( ltid )
+                                                       locker2 = TXN_ID( ltid );
+                                       } else {
+                                               ltid = tid;
                                        }
-                                       if ( rc == 0 ) {
-                                               bdb_cache_entry_db_relock( bdb->bi_dbenv, locker,
+                                       /* Give up original read lock, obtain write lock with
+                                        * (possibly) new locker ID.
+                                        */
+                                   if ( rc == 0 ) {
+                                               rc = bdb_cache_entry_db_relock( bdb->bi_dbenv, locker2,
                                                        *eip, 1, 0, lock );
-                                               /* Make sure no other modifier beat us to it */
-                                               if ( (*eip)->bei_e ) {
-                                                       bdb_entry_return( ep );
-                                                       ep = NULL;
-                                               } else {
-                                                       ep->e_private = *eip;
+                                       }
+                                       if ( rc == 0 && !ep) {
+                                               rc = bdb_id2entry( op->o_bd, ltid, id, &ep );
+                                       }
+                                       if ( rc == 0 ) {
+                                               ep->e_private = *eip;
 #ifdef BDB_HIER
-                                                       bdb_fix_dn( ep, 0 );
+                                               bdb_fix_dn( ep, 0 );
 #endif
-                                                       (*eip)->bei_e = ep;
-                                               }
-                                               bdb_cache_entry_db_relock( bdb->bi_dbenv, locker,
+                                               (*eip)->bei_e = ep;
+                                               ep = NULL;
+                                       }
+                                       (*eip)->bei_state ^= CACHE_ENTRY_LOADING;
+                                       if ( rc == 0 ) {
+                                               /* If we succeeded, downgrade back to a readlock. */
+                                               rc = bdb_cache_entry_db_relock( bdb->bi_dbenv, locker,
                                                        *eip, 0, 0, lock );
+                                       } else {
+                                               /* Otherwise, release the lock. */
+                                               bdb_cache_entry_db_unlock( bdb->bi_dbenv, lock );
                                        }
-                               } else {
-                                       /* If we had the entry already, this item
-                                        * is on the LRU list.
+                                       if ( locker2 != locker ) {
+                                               /* If we're using the per-thread txn, release all
+                                                * of its page locks now.
+                                                */
+                                               DB_LOCKREQ list;
+                                               list.op = DB_LOCK_PUT_ALL;
+                                               list.obj = NULL;
+                                               bdb->bi_dbenv->lock_vec( bdb->bi_dbenv, locker2,
+                                                       0, &list, 1, NULL );
+                                       }
+                               } else if ( !(*eip)->bei_e ) {
+                                       /* Some other thread is trying to load the entry,
+                                        * give it a chance to finish.
                                         */
-                                       lru_del = 1;
+                                       bdb_cache_entry_db_unlock( bdb->bi_dbenv, lock );
+                                       ldap_pvt_thread_yield();
+                                       bdb_cache_entryinfo_lock( *eip );
+                                       islocked = 1;
+                                       goto load1;
 #ifdef BDB_HIER
+                               } else {
+                                       /* Check for subtree renames
+                                        */
                                        rc = bdb_fix_dn( (*eip)->bei_e, 1 );
                                        if ( rc ) {
                                                bdb_cache_entry_db_relock( bdb->bi_dbenv,
@@ -705,11 +755,17 @@ again:    ldap_pvt_thread_rdwr_rlock( &bdb->bi_cache.c_rwlock );
                        }
                }
        }
+       if ( islocked ) {
+               bdb_cache_entryinfo_unlock( *eip );
+       }
+       if ( ep ) {
+               bdb_entry_return( ep );
+       }
        if ( rc == 0 ) {
                /* set lru mutex */
                ldap_pvt_thread_mutex_lock( &bdb->bi_cache.lru_mutex );
-               /* if entry is old, remove from old spot on LRU list */
-               if ( lru_del ) {
+               /* if entry is on LRU list, remove from old spot */
+               if ( (*eip)->bei_lrunext || (*eip)->bei_lruprev ) {
                        LRU_DELETE( &bdb->bi_cache, *eip );
                } else {
                /* if entry is new, bump cache size */
@@ -719,9 +775,6 @@ again:      ldap_pvt_thread_rdwr_rlock( &bdb->bi_cache.c_rwlock );
                bdb_cache_lru_add( bdb, locker, *eip );
        }
 
-       if ( islocked ) {
-               bdb_cache_entryinfo_unlock( *eip );
-       }
        return rc;
 }
 
@@ -785,7 +838,10 @@ bdb_cache_add(
 
        rc = bdb_entryinfo_add_internal( bdb, &ei, &new );
        /* bdb_csn_commit can cause this when adding the database root entry */
-       if ( new->bei_e ) bdb_entry_return( new->bei_e );
+       if ( new->bei_e ) {
+               new->bei_e->e_private = NULL;
+               bdb_entry_return( new->bei_e );
+       }
        new->bei_e = e;
        e->e_private = new;
        new->bei_state = CACHE_ENTRY_NO_KIDS | CACHE_ENTRY_NO_GRANDKIDS;
@@ -1069,6 +1125,10 @@ bdb_cache_release_all( Cache *cache )
 
        avl_free( cache->c_dntree.bei_kids, NULL );
        avl_free( cache->c_idtree, bdb_entryinfo_release );
+       for (;cache->c_eifree;cache->c_eifree = cache->c_lruhead) {
+               cache->c_lruhead = cache->c_eifree->bei_lrunext;
+               bdb_cache_entryinfo_destroy(cache->c_eifree);
+       }
        cache->c_lruhead = NULL;
        cache->c_lrutail = NULL;
 
@@ -1097,6 +1157,60 @@ bdb_lru_print( Cache *cache )
 }
 #endif
 
+static void
+bdb_txn_free( void *key, void *data )
+{
+       DB_TXN *txn = data;
+       TXN_ABORT( txn );
+}
+
+/* Obtain a long-lived transaction for the current thread */
+static int
+bdb_txn_get( Operation *op, DB_ENV *env, DB_TXN **txn )
+{
+       int i, rc, lockid;
+       void *ctx, *data;
+
+       /* If no op was provided, try to find the ctx anyway... */
+       if ( op ) {
+               ctx = op->o_threadctx;
+       } else {
+               ctx = ldap_pvt_thread_pool_context();
+       }
+
+       /* Shouldn't happen unless we're single-threaded */
+       if ( !ctx ) {
+               *txn = NULL;
+               return 0;
+       }
+
+       if ( ldap_pvt_thread_pool_getkey( ctx, ((char *)env)+1, &data, NULL ) ) {
+               for ( i=0, rc=1; rc != 0 && i<4; i++ ) {
+                       rc = TXN_BEGIN( env, NULL, txn, 0 );
+                       if (rc) ldap_pvt_thread_yield();
+               }
+               if ( rc != 0) {
+                       return rc;
+               }
+               if ( ( rc = ldap_pvt_thread_pool_setkey( ctx, ((char *)env)+1,
+                       *txn, bdb_txn_free ) ) ) {
+                       TXN_ABORT( *txn );
+#ifdef NEW_LOGGING
+                       LDAP_LOG( BACK_BDB, ERR, "bdb_txn_get: err %s(%d)\n",
+                               db_strerror(rc), rc, 0 );
+#else
+                       Debug( LDAP_DEBUG_ANY, "bdb_txn_get: err %s(%d)\n",
+                               db_strerror(rc), rc, 0 );
+#endif
+
+                       return rc;
+               }
+       } else {
+               *txn = data;
+       }
+       return 0;
+}
+
 #ifdef BDB_REUSE_LOCKERS
 static void
 bdb_locker_id_free( void *key, void *data )
@@ -1117,10 +1231,9 @@ bdb_locker_id_free( void *key, void *data )
                        "bdb_locker_id_free: %d err %s(%d)\n",
                        lockid, db_strerror(rc), rc );
 #endif
-               memset( &lr, 0, sizeof(lr) );
-
                /* release all locks held by this locker. */
                lr.op = DB_LOCK_PUT_ALL;
+               lr.obj = NULL;
                env->lock_vec( env, lockid, 0, &lr, 1, NULL );
                XLOCK_ID_FREE( env, lockid );
        }
index 31164d91c7a1c79d72cb42f5c34d0ac867051cb9..4d2dbbbaba7a456457e8247faf781793cf39438d 100644 (file)
@@ -172,7 +172,6 @@ bdb_db_config(
                        bdb->bi_search_stack_depth = MINIMUM_SEARCH_STACK_DEPTH;
                }
 
-#ifdef SLAP_IDL_CACHE
        /* size of the IDL cache in entries */
        } else if ( strcasecmp( argv[0], "idlcachesize" ) == 0 ) {
                if ( argc < 2 ) {
@@ -183,8 +182,6 @@ bdb_db_config(
                }
                if ( !( slapMode & SLAP_TOOL_MODE ) )
                        bdb->bi_idl_cache_max_size = atoi( argv[1] );
-#endif
-
        } else if ( strcasecmp( argv[0], "sessionlog" ) == 0 ) {
                int se_id = 0, se_size = 0;
                struct slap_session_entry *sent;
index 294362430fc618a7b5d7f1d326548c18e3e859b9..7c2b31ec366244d775d8dafc561c6a3b0ed7ef76 100644 (file)
@@ -39,7 +39,6 @@ bdb_csn_commit(
 )
 {
        struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
-       struct berval   ctxcsn_ndn = BER_BVNULL;
        EntryInfo               *ctxcsn_ei = NULL;
        DB_LOCK                 ctxcsn_lock;
        struct berval   max_committed_csn;
@@ -51,20 +50,17 @@ bdb_csn_commit(
        size_t                  textlen = sizeof textbuf;
        EntryInfo               *eip = NULL;
 
+       assert( !BER_BVISNULL( &op->o_bd->be_context_csn ) );
+
        if ( ei ) {
                e = ei->bei_e;
        }
 
-       build_new_dn( &ctxcsn_ndn, &op->o_bd->be_nsuffix[0],
-               (struct berval *)&slap_ldapsync_cn_bv, op->o_tmpmemctx );
-
-       rc =  bdb_dn2entry( op, tid, &ctxcsn_ndn, &ctxcsn_ei,
+       rc =  bdb_dn2entry( op, tid, &op->o_bd->be_context_csn, &ctxcsn_ei,
                        1, locker, &ctxcsn_lock );
        
        *ctxcsn_e = ctxcsn_ei->bei_e;
 
-       op->o_tmpfree( ctxcsn_ndn.bv_val, op->o_tmpmemctx );
-
        slap_get_commit_csn( op, &max_committed_csn );
 
        if ( max_committed_csn.bv_val == NULL ) {
@@ -78,7 +74,7 @@ bdb_csn_commit(
                if ( !*ctxcsn_e ) {
                        rs->sr_err = LDAP_OTHER;
                        rs->sr_text = "context csn not present";
-                       ch_free( max_committed_csn.bv_val );
+                       op->o_tmpfree( max_committed_csn.bv_val, op->o_tmpmemctx );
                        return BDB_CSN_ABORT;
                } else {
                        Modifications mod;
@@ -99,7 +95,7 @@ bdb_csn_commit(
                        dummy = **ctxcsn_e;
                        ret = bdb_modify_internal( op, tid, &mod, &dummy,
                                                                        &rs->sr_text, textbuf, textlen );                                                      
-                       ch_free( max_committed_csn.bv_val );
+                       op->o_tmpfree( max_committed_csn.bv_val, op->o_tmpmemctx );
                        if ( ret != LDAP_SUCCESS ) {
 #ifdef NEW_LOGGING
                                LDAP_LOG ( OPERATION, ERR,
@@ -158,7 +154,7 @@ bdb_csn_commit(
                }
 
                *ctxcsn_e = slap_create_context_csn_entry( op->o_bd, &max_committed_csn );
-               ch_free( max_committed_csn.bv_val );
+               op->o_tmpfree( max_committed_csn.bv_val, op->o_tmpmemctx );
                (*ctxcsn_e)->e_id = ctxcsn_id;
                *ctxcsn_added = 1;
 
@@ -245,7 +241,6 @@ bdb_get_commit_csn(
 )
 {
        struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
-       struct berval ctxcsn_ndn = BER_BVNULL;
        struct berval csn = BER_BVNULL;
        EntryInfo       *ctxcsn_ei = NULL;
        EntryInfo       *suffix_ei = NULL;
@@ -264,34 +259,34 @@ bdb_get_commit_csn(
        if ( op->o_sync_mode != SLAP_SYNC_NONE &&
                 !LDAP_STAILQ_EMPTY( &op->o_bd->be_syncinfo )) {
                char substr[67];
+               struct berval ctxcsn_ndn = BER_BVNULL;
                struct berval bv;
 
                LDAP_STAILQ_FOREACH( si, &op->o_bd->be_syncinfo, si_next ) {
                        sprintf( substr, "cn=syncrepl%ld", si->si_rid );
                        ber_str2bv( substr, 0, 0, &bv );
-                       build_new_dn( &ctxcsn_ndn, &op->o_bd->be_nsuffix[0], &bv, NULL );
+                       build_new_dn( &ctxcsn_ndn, &op->o_bd->be_nsuffix[0], &bv, op->o_tmpmemctx );
 
 consumer_ctxcsn_retry :
                        rs->sr_err = bdb_dn2entry( op, NULL, &ctxcsn_ndn, &ctxcsn_ei,
                                                                                0, locker, ctxcsn_lock );
                        switch(rs->sr_err) {
+                       case DB_LOCK_DEADLOCK:
+                       case DB_LOCK_NOTGRANTED:
+                               goto consumer_ctxcsn_retry;
                        case 0:
-                               ch_free( ctxcsn_ndn.bv_val );
+                               op->o_tmpfree( ctxcsn_ndn.bv_val, op->o_tmpmemctx );
                                ctxcsn_ndn.bv_val = NULL;
                                if ( ctxcsn_ei ) {
                                        ctxcsn_e = ctxcsn_ei->bei_e;
                                }
                                break;
-                       case LDAP_BUSY:
-                               goto done;
-                       case DB_LOCK_DEADLOCK:
-                       case DB_LOCK_NOTGRANTED:
-                               goto consumer_ctxcsn_retry;
                        case DB_NOTFOUND:
-                               rs->sr_err = LDAP_OTHER;
-                               goto done;
                        default:
                                rs->sr_err = LDAP_OTHER;
+                       case LDAP_BUSY:
+                               op->o_tmpfree( ctxcsn_ndn.bv_val, op->o_tmpmemctx );
+                               ctxcsn_ndn.bv_val = NULL;
                                goto done;
                        }
 
@@ -333,11 +328,9 @@ consumer_ctxcsn_retry :
                }
        } else if ( op->o_sync_mode != SLAP_SYNC_NONE &&
                 LDAP_STAILQ_EMPTY( &op->o_bd->be_syncinfo )) {
-               build_new_dn( &ctxcsn_ndn, &op->o_bd->be_nsuffix[0],
-                                       (struct berval *)&slap_ldapsync_cn_bv, NULL );
 
 provider_ctxcsn_retry :
-               rs->sr_err = bdb_dn2entry( op, NULL, &ctxcsn_ndn, &ctxcsn_ei,
+               rs->sr_err = bdb_dn2entry( op, NULL, &op->o_bd->be_context_csn, &ctxcsn_ei,
                                                                        0, locker, ctxcsn_lock );
                switch(rs->sr_err) {
                case 0:
@@ -401,10 +394,8 @@ txn_retry:
                                goto done;
                        }
 
-                       rs->sr_err = bdb_dn2entry( op, NULL, &ctxcsn_ndn, &ctxcsn_ei,
+                       rs->sr_err = bdb_dn2entry( op, NULL, &op->o_bd->be_context_csn, &ctxcsn_ei,
                                     0, ctxcsn_locker, ctxcsn_lock );
-                       ch_free( ctxcsn_ndn.bv_val );
-                       ctxcsn_ndn.bv_val = NULL;
 
                        if ( ctxcsn_ei ) {
                                ctxcsn_e = ctxcsn_ei->bei_e;
@@ -437,8 +428,5 @@ done:
         TXN_ABORT( ltid );
     }
 
-       if ( ctxcsn_ndn.bv_val != NULL )
-               ch_free( ctxcsn_ndn.bv_val );
-
        return rs->sr_err;
 }
index 528c57815f15089372f2b11178150b740a4b9c08..14e94d301dd4f541e3cfaeb799980c96c2a16e9a 100644 (file)
@@ -382,7 +382,6 @@ bdb_dn2id_children(
        ((char *)key.data)[0] = DN_ONE_PREFIX;
        AC_MEMCPY( &((char *)key.data)[1], e->e_nname.bv_val, key.size - 1 );
 
-#ifdef SLAP_IDL_CACHE
        if ( bdb->bi_idl_cache_size ) {
                rc = bdb_idl_cache_get( bdb, db, &key, NULL );
                if ( rc != LDAP_NO_SUCH_OBJECT ) {
@@ -390,7 +389,6 @@ bdb_dn2id_children(
                        return rc;
                }
        }
-#endif
        /* we actually could do a empty get... */
        DBTzero( &data );
        data.data = &id;
@@ -642,11 +640,9 @@ hdb_dn2id_add(
                db->put( db, txn, &key, &data, DB_NODUPDATA );
        }
 
-#ifdef SLAP_IDL_CACHE
        if ( bdb->bi_idl_cache_size ) {
                bdb_idl_cache_del( bdb, db, &key );
        }
-#endif
        data.data = d;
        data.size = sizeof(diskNode) + rlen + nrlen;
        data.flags = DB_DBT_USERMEM;
@@ -692,11 +688,9 @@ hdb_dn2id_delete(
        data.dlen = data.size;
        data.flags = DB_DBT_USERMEM | DB_DBT_PARTIAL;
 
-#ifdef SLAP_IDL_CACHE
        if ( bdb->bi_idl_cache_size ) {
                bdb_idl_cache_del( bdb, db, &key );
        }
-#endif
        rc = db->cursor( db, txn, &cursor, bdb->bi_db_opflags );
        if ( rc ) return rc;
 
@@ -863,14 +857,12 @@ hdb_dn2id_children(
        key.data = &e->e_id;
        key.flags = DB_DBT_USERMEM;
 
-#ifdef SLAP_IDL_CACHE
        if ( bdb->bi_idl_cache_size ) {
                rc = bdb_idl_cache_get( bdb, db, &key, NULL );
                if ( rc != LDAP_NO_SUCH_OBJECT ) {
                        return rc;
                }
        }
-#endif
        DBTzero(&data);
        data.data = &d;
        data.ulen = sizeof(d);
@@ -938,7 +930,6 @@ hdb_dn2idl_internal(
        struct dn2id_cookie *cx
 )
 {
-#ifdef SLAP_IDL_CACHE
        if ( cx->bdb->bi_idl_cache_size ) {
                cx->rc = bdb_idl_cache_get(cx->bdb, cx->db, &cx->key, cx->tmp);
                if ( cx->rc == DB_NOTFOUND ) {
@@ -948,7 +939,6 @@ hdb_dn2idl_internal(
                        goto gotit;
                }
        }
-#endif
        BDB_IDL_ZERO( cx->tmp );
 
        if ( !cx->ei ) {
@@ -1044,11 +1034,9 @@ hdb_dn2idl_internal(
        }
 
 saveit:
-#ifdef SLAP_IDL_CACHE
        if ( cx->bdb->bi_idl_cache_max_size ) {
                bdb_idl_cache_put( cx->bdb, cx->db, &cx->key, cx->tmp, cx->rc );
        }
-#endif
        ;
 gotit:
        if ( !BDB_IDL_IS_ZERO( cx->tmp )) {
index fce1fcdc637266ec84f2a2a67ac290785be08328..d4eb26711119a21037a44c44bfb0832f1362fcf5 100644 (file)
@@ -202,6 +202,10 @@ int bdb_entry_release(
                        SLAP_TRUNCATE_MODE, SLAP_UNDEFINED_MODE */
  
        if ( slapMode == SLAP_SERVER_MODE ) {
+               /* If not in our cache, just free it */
+               if ( !e->e_private ) {
+                       return bdb_entry_return( e );
+               }
                /* free entry and reader or writer lock */
                if ( o ) {
                        boi = (struct bdb_op_info *)o->o_private;
index d6a29083d641719cecf2c567ee33c91c6de4f58e..a7980a3f7abc67aec04a6d97e5f95a47b2c3c8e4 100644 (file)
@@ -27,7 +27,6 @@
 
 #define IDL_CMP(x,y)   ( x < y ? -1 : ( x > y ? 1 : 0 ) )
 
-#ifdef SLAP_IDL_CACHE
 #define IDL_LRU_DELETE( bdb, e ) do {                                  \
        if ( e->idl_lru_prev != NULL ) {                                \
                e->idl_lru_prev->idl_lru_next = e->idl_lru_next;        \
@@ -63,7 +62,6 @@ bdb_idl_entry_cmp( const void *v_idl1, const void *v_idl2 )
        if ((rc = idl1->kstr.bv_len - idl2->kstr.bv_len )) return rc;
        return ( memcmp ( idl1->kstr.bv_val, idl2->kstr.bv_val , idl1->kstr.bv_len ) );
 }
-#endif
 
 #if IDL_DEBUG > 0
 static void idl_check( ID *ids )
@@ -304,8 +302,6 @@ bdb_show_key(
        }
 }
 
-#ifdef SLAP_IDL_CACHE
-
 /* Find a db/key pair in the IDL cache. If ids is non-NULL,
  * copy the cached IDL into it, otherwise just return the status.
  */
@@ -444,7 +440,6 @@ bdb_idl_cache_del(
        }
        ldap_pvt_thread_rdwr_wunlock( &bdb->bi_idl_tree_rwlock );
 }
-#endif
 
 int
 bdb_idl_fetch_key(
@@ -495,12 +490,10 @@ bdb_idl_fetch_key(
 
        assert( ids != NULL );
 
-#ifdef SLAP_IDL_CACHE
        if ( bdb->bi_idl_cache_size ) {
                rc = bdb_idl_cache_get( bdb, db, key, ids );
                if ( rc != LDAP_NO_SUCH_OBJECT ) return rc;
        }
-#endif
 
        DBTzero( &data );
 
@@ -576,9 +569,7 @@ bdb_idl_fetch_key(
        }
 
        if( rc == DB_NOTFOUND ) {
-#ifndef SLAP_IDL_CACHE
                return rc;
-#endif
 
        } else if( rc != 0 ) {
 #ifdef NEW_LOGGING
@@ -619,11 +610,9 @@ bdb_idl_fetch_key(
                return -1;
        }
 
-#ifdef SLAP_IDL_CACHE
        if ( bdb->bi_idl_cache_max_size ) {
                bdb_idl_cache_put( bdb, db, key, ids, rc );
        }
-#endif
 
        return rc;
 }
@@ -659,11 +648,9 @@ bdb_idl_insert_key(
 
        assert( id != NOID );
 
-#ifdef SLAP_IDL_CACHE
        if ( bdb->bi_idl_cache_size ) {
                bdb_idl_cache_del( bdb, db, key );
        }
-#endif
 
        DBTzero( &data );
        data.size = sizeof( ID );
@@ -856,11 +843,9 @@ bdb_idl_delete_key(
        }
        assert( id != NOID );
 
-#ifdef SLAP_IDL_CACHE
        if ( bdb->bi_idl_cache_max_size ) {
                bdb_idl_cache_del( bdb, db, key );
        }
-#endif
 
        DBTzero( &data );
        data.data = &tmp;
index 9742b9ca24bd3e513be4c7fa2cc7d678a1968994..e9f616c602f76059a5717aa1521d4d21fbed77ed 100644 (file)
@@ -71,8 +71,8 @@ bdb_db_init( BackendDB *be )
        LDAP_LOG( BACK_BDB, ENTRY, "bdb_db_init", 0, 0, 0 );
 #else
        Debug( LDAP_DEBUG_ANY,
-               "bdb_db_init: Initializing BDB database\n",
-               0, 0, 0 );
+               "bdb_db_init: Initializing %s database\n",
+               be->bd_info->bi_type, 0, 0 );
 #endif
 
        /* allocate backend-database-specific stuff */
@@ -196,14 +196,15 @@ bdb_db_open( BackendDB *be )
        bdb->bi_dbenv->set_errcall( bdb->bi_dbenv, bdb_errcall );
        bdb->bi_dbenv->set_lk_detect( bdb->bi_dbenv, bdb->bi_lock_detect );
 
-#ifdef SLAP_IDL_CACHE
+       /* One long-lived TXN per thread, two TXNs per write op */
+       bdb->bi_dbenv->set_tx_max( bdb->bi_dbenv, connection_pool_max * 3 );
+
        if ( bdb->bi_idl_cache_max_size ) {
                bdb->bi_idl_tree = NULL;
                ldap_pvt_thread_rdwr_init( &bdb->bi_idl_tree_rwlock );
                ldap_pvt_thread_mutex_init( &bdb->bi_idl_tree_lrulock );
                bdb->bi_idl_cache_size = 0;
        }
-#endif
 
 #ifdef BDB_SUBDIRS
        {
@@ -447,7 +448,7 @@ bdb_db_open( BackendDB *be )
                return rc;
        }
 
-       bdb->bi_dbenv->lock_id(bdb->bi_dbenv, &bdb->bi_cache.c_locker);
+       XLOCK_ID(bdb->bi_dbenv, &bdb->bi_cache.c_locker);
 
        /* <insert> open (and create) index databases */
        return 0;
@@ -459,9 +460,7 @@ bdb_db_close( BackendDB *be )
        int rc;
        struct bdb_info *bdb = (struct bdb_info *) be->be_private;
        struct bdb_db_info *db;
-#ifdef SLAP_IDL_CACHE
        bdb_idl_cache_entry_t *entry, *next_entry;
-#endif
 
        while( bdb->bi_ndatabases-- ) {
                db = bdb->bi_databases[bdb->bi_ndatabases];
@@ -476,7 +475,6 @@ bdb_db_close( BackendDB *be )
 
        bdb_cache_release_all (&bdb->bi_cache);
 
-#ifdef SLAP_IDL_CACHE
        if ( bdb->bi_idl_cache_max_size ) {
                ldap_pvt_thread_rdwr_wlock ( &bdb->bi_idl_tree_rwlock );
                avl_free( bdb->bi_idl_tree, NULL );
@@ -491,7 +489,8 @@ bdb_db_close( BackendDB *be )
                }
                ldap_pvt_thread_rdwr_wunlock ( &bdb->bi_idl_tree_rwlock );
        }
-#endif
+
+       XLOCK_ID_FREE(bdb->bi_dbenv, bdb->bi_cache.c_locker);
 
        return 0;
 }
@@ -542,12 +541,10 @@ bdb_db_destroy( BackendDB *be )
        ldap_pvt_thread_rdwr_destroy ( &bdb->bi_pslist_rwlock );
        ldap_pvt_thread_mutex_destroy( &bdb->bi_lastid_mutex );
        ldap_pvt_thread_mutex_destroy( &bdb->bi_database_mutex );
-#ifdef SLAP_IDL_CACHE
        if ( bdb->bi_idl_cache_max_size ) {
                ldap_pvt_thread_rdwr_destroy( &bdb->bi_idl_tree_rwlock );
                ldap_pvt_thread_mutex_destroy( &bdb->bi_idl_tree_lrulock );
        }
-#endif
 
        ch_free( bdb );
        be->be_private = NULL;
index ce0195e35d5a01a5bb5879780b36fdc4900a17b1..45d2efeb11eb9516fd8a87b3a5f4db93d7d5949f 100644 (file)
@@ -266,6 +266,10 @@ int bdb_modify_internal(
        rc = entry_schema_check( op->o_bd, e, save_attrs, text, textbuf, textlen );
        if ( rc != LDAP_SUCCESS || op->o_noop ) {
                attrs_free( e->e_attrs );
+               /* clear the indexing flags */
+               for ( ap = save_attrs; ap != NULL; ap = ap->a_next ) {
+                       ap->a_flags = 0;
+               }
                e->e_attrs = save_attrs;
 
                if ( rc != LDAP_SUCCESS ) {
@@ -349,7 +353,7 @@ bdb_modify( Operation *op, SlapReply *rs )
        size_t textlen = sizeof textbuf;
        DB_TXN  *ltid = NULL, *lt2;
        struct bdb_op_info opinfo;
-       Entry           dummy;
+       Entry           dummy = {0};
 
        u_int32_t       locker = 0;
        DB_LOCK         lock;
@@ -380,6 +384,10 @@ bdb_modify( Operation *op, SlapReply *rs )
 
        if( 0 ) {
 retry: /* transaction retry */
+               if ( dummy.e_attrs ) {
+                       attrs_free( dummy.e_attrs );
+                       dummy.e_attrs = NULL;
+               }
                if( e != NULL ) {
                        bdb_unlocked_cache_return_entry_w(&bdb->bi_cache, e);
                        e = NULL;
@@ -615,11 +623,11 @@ retry:    /* transaction retry */
                if ( (rs->sr_err == LDAP_INSUFFICIENT_ACCESS) && opinfo.boi_err ) {
                        rs->sr_err = opinfo.boi_err;
                }
+               /* Only free attrs if they were dup'd.  */
+               if ( dummy.e_attrs == e->e_attrs ) dummy.e_attrs = NULL;
                switch( rs->sr_err ) {
                case DB_LOCK_DEADLOCK:
                case DB_LOCK_NOTGRANTED:
-                       attrs_free( dummy.e_attrs ); 
-                       dummy.e_attrs = NULL;
                        goto retry;
                }
                goto return_results;
@@ -639,8 +647,6 @@ retry:      /* transaction retry */
                switch( rs->sr_err ) {
                case DB_LOCK_DEADLOCK:
                case DB_LOCK_NOTGRANTED:
-                       attrs_free( dummy.e_attrs ); 
-                       dummy.e_attrs = NULL;
                        goto retry;
                }
                rs->sr_text = "entry update failed";
@@ -660,8 +666,6 @@ retry:      /* transaction retry */
                case BDB_CSN_ABORT :
                        goto return_results;
                case BDB_CSN_RETRY :
-                       attrs_free( dummy.e_attrs ); 
-                       dummy.e_attrs = NULL;
                        goto retry;
                }
        }
@@ -671,7 +675,7 @@ retry:      /* transaction retry */
                        postread_ctrl = &ctrls[num_ctrls++];
                        ctrls[num_ctrls] = NULL;
                }
-               if( slap_read_controls( op, rs, e,
+               if( slap_read_controls( op, rs, &dummy,
                        &slap_post_read_bv, postread_ctrl ) )
                {
 #ifdef NEW_LOGGING
@@ -697,10 +701,9 @@ retry:     /* transaction retry */
                switch( rc ) {
                case DB_LOCK_DEADLOCK:
                case DB_LOCK_NOTGRANTED:
-                       attrs_free( dummy.e_attrs ); 
-                       dummy.e_attrs = NULL;
                        goto retry;
                }
+               dummy.e_attrs = NULL;
 
                if ( LDAP_STAILQ_EMPTY( &op->o_bd->be_syncinfo )) {
                        if ( ctxcsn_added ) {
@@ -788,6 +791,9 @@ retry:      /* transaction retry */
        if( num_ctrls ) rs->sr_ctrls = ctrls;
 
 return_results:
+       if( dummy.e_attrs ) {
+               attrs_free( dummy.e_attrs );
+       }
        send_ldap_result( op, rs );
 
        if( rs->sr_err == LDAP_SUCCESS && bdb->bi_txn_cp ) {
index 8d29504e7cf869ef2932866d2c2766e54a234d17..0956d8cdfd01a903432ed0f85b3c0a6b09d39f88 100644 (file)
@@ -41,7 +41,7 @@ bdb_modrdn( Operation *op, SlapReply *rs )
        size_t textlen = sizeof textbuf;
        DB_TXN          *ltid = NULL, *lt2;
        struct bdb_op_info opinfo;
-       Entry dummy, *save;
+       Entry dummy = {0};
 
        ID                      id;
 
@@ -89,6 +89,10 @@ bdb_modrdn( Operation        *op, SlapReply *rs )
 
        if( 0 ) {
 retry: /* transaction retry */
+               if ( dummy.e_attrs ) {
+                       attrs_free( dummy.e_attrs );
+                       dummy.e_attrs = NULL;
+               }
                if (e != NULL) {
                        bdb_unlocked_cache_return_entry_w(&bdb->bi_cache, e);
                        e = NULL;
@@ -829,11 +833,7 @@ retry:     /* transaction retry */
                goto return_results;
        }
 
-       dummy = *e;
-       save = e;
-       e = &dummy;
-
-       /* delete old one */
+       /* delete old DN */
        rs->sr_err = bdb_dn2id_delete( op, lt2, eip, e );
        if ( rs->sr_err != 0 ) {
 #ifdef NEW_LOGGING
@@ -855,24 +855,14 @@ retry:    /* transaction retry */
                goto return_results;
        }
 
-       /* Binary format uses a single contiguous block, cannot
-        * free individual fields. But if a previous modrdn has
-        * already happened, must free the names. The frees are
-        * done in bdb_cache_modrdn().
-        */
-       if( e->e_nname.bv_val < e->e_bv.bv_val ||
-               e->e_nname.bv_val > e->e_bv.bv_val + e->e_bv.bv_len )
-       {
-               e->e_name.bv_val = NULL;
-               e->e_nname.bv_val = NULL;
-       }
-       e->e_name = new_dn;
-       e->e_nname = new_ndn;
-       new_dn.bv_val = NULL;
-       new_ndn.bv_val = NULL;
+       /* copy the entry, then override some fields */
+       dummy = *e;
+       dummy.e_name = new_dn;
+       dummy.e_nname = new_ndn;
+       dummy.e_attrs = NULL;
 
-       /* add new one */
-       rs->sr_err = bdb_dn2id_add( op, lt2, neip ? neip : eip, e );
+       /* add new DN */
+       rs->sr_err = bdb_dn2id_add( op, lt2, neip ? neip : eip, &dummy );
        if ( rs->sr_err != 0 ) {
 #ifdef NEW_LOGGING
                LDAP_LOG ( OPERATION, ERR, 
@@ -893,10 +883,12 @@ retry:    /* transaction retry */
                goto return_results;
        }
 
+       dummy.e_attrs = e->e_attrs;
+
        if ( rs->sr_err == LDAP_SUCCESS && !op->o_noop && !op->o_no_psearch ) {
                ldap_pvt_thread_rdwr_wlock( &bdb->bi_pslist_rwlock );
                LDAP_LIST_FOREACH ( ps_list, &bdb->bi_psearch_list, o_ps_link ) {
-                       rc = bdb_psearch( op, rs, ps_list, e, LDAP_PSEARCH_BY_PREMODIFY );
+                       rc = bdb_psearch( op, rs, ps_list, &dummy, LDAP_PSEARCH_BY_PREMODIFY );
                        if ( rc ) {
 #ifdef NEW_LOGGING
                                LDAP_LOG ( OPERATION, ERR,
@@ -912,8 +904,9 @@ retry:      /* transaction retry */
                ldap_pvt_thread_rdwr_wunlock( &bdb->bi_pslist_rwlock );
        }
 
+
        /* modify entry */
-       rs->sr_err = bdb_modify_internal( op, lt2, &mod[0], e,
+       rs->sr_err = bdb_modify_internal( op, lt2, &mod[0], &dummy,
                &rs->sr_text, textbuf, textlen );
        if( rs->sr_err != LDAP_SUCCESS ) {
 #ifdef NEW_LOGGING
@@ -928,6 +921,7 @@ retry:      /* transaction retry */
                if ( ( rs->sr_err == LDAP_INSUFFICIENT_ACCESS ) && opinfo.boi_err ) {
                        rs->sr_err = opinfo.boi_err;
                }
+               if ( dummy.e_attrs == e->e_attrs ) dummy.e_attrs = NULL;
                switch( rs->sr_err ) {
                case DB_LOCK_DEADLOCK:
                case DB_LOCK_NOTGRANTED:
@@ -937,7 +931,7 @@ retry:      /* transaction retry */
        }
 
        /* id2entry index */
-       rs->sr_err = bdb_id2entry_update( op->o_bd, lt2, e );
+       rs->sr_err = bdb_id2entry_update( op->o_bd, lt2, &dummy );
        if ( rs->sr_err != 0 ) {
 #ifdef NEW_LOGGING
                LDAP_LOG ( OPERATION, ERR, 
@@ -1010,7 +1004,7 @@ retry:    /* transaction retry */
                        postread_ctrl = &ctrls[num_ctrls++];
                        ctrls[num_ctrls] = NULL;
                }
-               if( slap_read_controls( op, rs, e,
+               if( slap_read_controls( op, rs, &dummy,
                        &slap_post_read_bv, postread_ctrl ) )
                {
 #ifdef NEW_LOGGING                                   
@@ -1033,13 +1027,16 @@ retry:  /* transaction retry */
                }
 
        } else {
-               rc = bdb_cache_modrdn( save, &op->orr_nnewrdn, e, neip,
+               rc = bdb_cache_modrdn( e, &op->orr_nnewrdn, &dummy, neip,
                        bdb->bi_dbenv, locker, &lock );
                switch( rc ) {
                case DB_LOCK_DEADLOCK:
                case DB_LOCK_NOTGRANTED:
                        goto retry;
                }
+               dummy.e_attrs = NULL;
+               new_dn.bv_val = NULL;
+               new_ndn.bv_val = NULL;
 
                if ( LDAP_STAILQ_EMPTY( &op->o_bd->be_syncinfo )) {
                        if ( ctxcsn_added ) {
@@ -1126,6 +1123,9 @@ retry:    /* transaction retry */
        if( num_ctrls ) rs->sr_ctrls = ctrls;
 
 return_results:
+       if ( dummy.e_attrs ) {
+               attrs_free( dummy.e_attrs );
+       }
        send_ldap_result( op, rs );
 
        if( rs->sr_err == LDAP_SUCCESS && bdb->bi_txn_cp ) {
index 52504708038d7377b141a21a6b730c8a496964c4..c239908eac44d5d39e98087464cc72c02f2ee01a 100644 (file)
@@ -39,7 +39,19 @@ bdb_hasSubordinates(
        
        assert( e );
 
+       /* NOTE: this should never happen, but it actually happens
+        * when using back-relay; until we find a better way to
+        * preserve entry's private information while rewriting it,
+        * let's disable the hasSubordinate feature for back-relay.
+        */
+       if ( BEI( e ) == NULL ) {
+               return LDAP_OTHER;
+       }
+
 retry:
+       /* FIXME: we can no longer assume the entry's e_private
+        * field is correctly populated; so we need to reacquire
+        * it with reader lock */
        rc = bdb_cache_children( op, NULL, e );
        
        switch( rc ) {
index 40a9f5a86788b538decb779960bbe3f768aef619..ccdb1aa505b0756e4abc77253b6c2b1ee91ca8d8 100644 (file)
@@ -203,7 +203,6 @@ BI_entry_get_rw bdb_entry_get;
 /*
  * idl.c
  */
-#ifdef SLAP_IDL_CACHE
 
 #define bdb_idl_cache_get                      BDB_SYMBOL(idl_cache_get)
 #define bdb_idl_cache_put                      BDB_SYMBOL(idl_cache_put)
@@ -228,7 +227,6 @@ bdb_idl_cache_del(
        struct bdb_info *bdb,
        DB              *db,
        DBT             *key );
-#endif
 
 #define bdb_idl_first                          BDB_SYMBOL(idl_first)
 #define bdb_idl_next                           BDB_SYMBOL(idl_next)
index 31a8776796c353338a434a7b98a1c93fdcde326f..5090c695f0f26de62b322afa6e76a144c476461f 100644 (file)
@@ -149,7 +149,7 @@ static int search_aliases(
        ID cursora, ida, cursoro, ido, *subscop2;
        Entry *matched, *a;
        EntryInfo *ei;
-       struct berval bv_alias = { sizeof("alias")-1, "alias" };
+       struct berval bv_alias = BER_BVC( "alias" );
        AttributeAssertion aa_alias;
        Filter  af;
        DB_LOCK locka, lockr;
@@ -215,9 +215,12 @@ static int search_aliases(
                        ida = bdb_idl_next(curscop, &cursora))
                {
                        ei = NULL;
+retry1:
                        rs->sr_err = bdb_cache_find_id(op, NULL,
                                ida, &ei, 0, locker, &lockr );
                        if (rs->sr_err != LDAP_SUCCESS) {
+                               if ( rs->sr_err == DB_LOCK_DEADLOCK ||
+                                       rs->sr_err == DB_LOCK_NOTGRANTED ) goto retry1;
                                continue;
                        }
                        a = ei->bei_e;
@@ -281,9 +284,15 @@ nextido:
                 * Set the name so that the scope's IDL can be retrieved.
                 */
                ei = NULL;
+sameido:
                rs->sr_err = bdb_cache_find_id(op, NULL, ido, &ei,
                        0, locker, &locka );
-               if ( rs->sr_err != LDAP_SUCCESS ) goto nextido;
+               if ( rs->sr_err != LDAP_SUCCESS ) {
+                       if ( rs->sr_err == DB_LOCK_DEADLOCK ||
+                               rs->sr_err == DB_LOCK_NOTGRANTED )
+                               goto sameido;
+                       goto nextido;
+               }
                e = ei->bei_e;
        }
        return rs->sr_err;
@@ -495,8 +504,7 @@ bdb_do_search( Operation *op, SlapReply *rs, Operation *sop,
        null_attr.an_desc = NULL;
        null_attr.an_oc = NULL;
        null_attr.an_oc_exclude = 0;
-       null_attr.an_name.bv_len = 0;
-       null_attr.an_name.bv_val = NULL;
+       BER_BVZERO( &null_attr.an_name );
 
        for( num_ctrls = 0; num_ctrls < SLAP_MAX_RESPONSE_CONTROLS; num_ctrls++ ) {
                ctrls[num_ctrls] = NULL;
@@ -508,8 +516,7 @@ bdb_do_search( Operation *op, SlapReply *rs, Operation *sop,
                attrs[0].an_desc = NULL;
                attrs[0].an_oc = NULL;
                attrs[0].an_oc_exclude = 0;
-               attrs[0].an_name.bv_len = 0;
-               attrs[0].an_name.bv_val = NULL;
+               BER_BVZERO( &attrs[0].an_name );
        }
 
        manageDSAit = get_manageDSAit( sop );
@@ -546,8 +553,8 @@ bdb_do_search( Operation *op, SlapReply *rs, Operation *sop,
                ei_root.bei_parent = &ei_root;
                e_root.e_private = &ei_root;
                e_root.e_id = 0;
-               e_root.e_nname.bv_val="";
-               e_root.e_name.bv_val="";
+               BER_BVSTR( &e_root.e_nname, "" );
+               BER_BVSTR( &e_root.e_name, "" );
                ei = &ei_root;
                rs->sr_err = LDAP_SUCCESS;
        } else {
@@ -1641,7 +1648,7 @@ static int search_candidates(
        {
                if( !get_manageDSAit(op) && !get_domainScope(op) ) {
                        /* match referral objects */
-                       struct berval bv_ref = { sizeof("referral")-1, "referral" };
+                       struct berval bv_ref = BER_BVC( "referral" );
                        rf.f_choice = LDAP_FILTER_EQUALITY;
                        rf.f_ava = &aa_ref;
                        rf.f_av_desc = slap_schema.si_ad_objectClass;
@@ -1665,7 +1672,7 @@ static int search_candidates(
 
 #ifdef BDB_SUBENTRIES
        if( get_subentries_visibility( op ) ) {
-               struct berval bv_subentry = { sizeof("SUBENTRY")-1, "SUBENTRY" };
+               struct berval bv_subentry = BER_BVC( "SUBENTRY" );
                sf.f_choice = LDAP_FILTER_EQUALITY;
                sf.f_ava = &aa_subentry;
                sf.f_av_desc = slap_schema.si_ad_objectClass;
@@ -1748,7 +1755,7 @@ send_paged_response(
                lastid ? *lastid : 0, rs->sr_nentries, NULL );
 #endif
 
-       ctrl.ldctl_value.bv_val = NULL;
+       BER_BVZERO( &ctrl.ldctl_value );
        ctrls[0] = &ctrl;
        ctrls[1] = NULL;
 
@@ -1761,8 +1768,7 @@ send_paged_response(
 
        } else {
                respcookie = ( PagedResultsCookie )0;
-               cookie.bv_val = "";
-               cookie.bv_len = 0;
+               BER_BVSTR( &cookie, "" );
        }
 
        op->o_conn->c_pagedresults_state.ps_cookie = respcookie;
index 4672273293f078b2e0e6f3955e857642aa12bc13..c978ae90cfc28f9b728764a566564e0219581a96 100644 (file)
@@ -53,7 +53,7 @@ slap_get_commit_csn( Operation *op, struct berval *csn )
                if ( csne->ce_state == SLAP_CSN_PENDING ) break;
        }
 
-       if ( committed_csne ) ber_dupbv( csn, committed_csne->ce_csn );
+       if ( committed_csne ) ber_dupbv_x( csn, committed_csne->ce_csn, op->o_tmpmemctx );
        ldap_pvt_thread_mutex_unlock( &op->o_bd->be_pcl_mutex );
 }
 
index b8a8e61c45d0f2ce62b6fc0fde8746f011e2dd4b..eb8aa71c3c1f76560af44576e864b52014e21513 100644 (file)
@@ -339,39 +339,44 @@ test_mra_vrFilter(
        int i, j;
 
        for ( i=0; a != NULL; a = a->a_next, i++ ) {
-               struct berval *bv, value;
+               struct berval *bv, assertedValue;
 
                if ( mra->ma_desc ) {
                        if ( !is_ad_subtype( a->a_desc, mra->ma_desc ) ) {
                                continue;
                        }
-                       value = mra->ma_value;
+                       assertedValue = mra->ma_value;
 
                } else {
                        int rc;
                        const char      *text = NULL;
 
                        /* check if matching is appropriate */
-                       if ( strcmp( mra->ma_rule->smr_syntax->ssyn_oid,
-                               a->a_desc->ad_type->sat_syntax->ssyn_oid ) != 0 ) {
+                       if ( !mr_usable_with_at( mra->ma_rule, a->a_desc->ad_type ) ) {
                                continue;
                        }
 
                        rc = asserted_value_validate_normalize( a->a_desc, mra->ma_rule,
                                SLAP_MR_EXT|SLAP_MR_VALUE_OF_ASSERTION_SYNTAX,
-                               &mra->ma_value, &value, &text, op->o_tmpmemctx );
+                               &mra->ma_value, &assertedValue, &text, op->o_tmpmemctx );
 
                        if( rc != LDAP_SUCCESS ) continue;
                }
 
-               bv = a->a_nvals;
+               /* check match */
+               if (mra->ma_rule == a->a_desc->ad_type->sat_equality) {
+                       bv = a->a_nvals;
+               } else {
+                       bv = a->a_vals;
+               }
+                                       
                for ( j = 0; bv->bv_val != NULL; bv++, j++ ) {
                        int ret;
                        int rc;
                        const char *text;
 
                        rc = value_match( &ret, a->a_desc, mra->ma_rule, 0,
-                               bv, &value, &text );
+                               bv, &assertedValue, &text );
                        if( rc != LDAP_SUCCESS ) {
                                return rc;
                        }
@@ -384,3 +389,4 @@ test_mra_vrFilter(
 
        return LDAP_SUCCESS;
 }
+