The default is
.BR LOCALSTATEDIR/openldap\-data .
.TP
+.BI idlcache \ <boolean>
+Use the in-memory idlcache. The default is true.
+.TP
+\fBindex \fR{\fI<attrlist>\fR|\fBdefault\fR} [\fBpres\fR,\fBeq\fR,\fBapprox\fR,\fBsub\fR,\fI<special>\fR]
+Specify the indexes to maintain for the given attribute (or
+list of attributes).
+Some attributes only support a subset of indexes.
+If only an \fI<attr>\fP is given, the indices specified for \fBdefault\fR
+are maintained.
+Note that setting a default does not imply that all attributes will be
+indexed. Also, for best performance, an
+.B eq
+index should always be configured for the
+.B objectClass
+attribute.
+.TP
+.BI mode \ <integer>
+back-wt does not support mode option. use umask instead.
+.TP
\fBwtconfig \fR{\fBcreate\fR,\fBcache_size=512M\fR,\fBasync=(enabled)\fR}
Specify configuration for wiredtiger, This parameter is pass to
.BR wiredtiger_open (3).
asynchronous operations configuration options. disabled by default.
.RE
.RS
-.TP
-\fBindex \fR{\fI<attrlist>\fR|\fBdefault\fR} [\fBpres\fR,\fBeq\fR,\fBapprox\fR,\fBsub\fR,\fI<special>\fR]
-Specify the indexes to maintain for the given attribute (or
-list of attributes).
-Some attributes only support a subset of indexes.
-If only an \fI<attr>\fP is given, the indices specified for \fBdefault\fR
-are maintained.
-Note that setting a default does not imply that all attributes will be
-indexed. Also, for best performance, an
-.B eq
-index should always be configured for the
-.B objectClass
-attribute.
.SH ACCESS CONTROL
The
## <http://www.OpenLDAP.org/license.html>.
SRCS = init.c tools.c config.c \
- add.c bind.c compare.c delete.c modify.c search.c \
- operational.c \
+ add.c bind.c compare.c delete.c modify.c modrdn.c search.c \
+ extended.c operational.c \
attr.c index.c key.c filterindex.c \
dn2entry.c dn2id.c id2entry.c idl.c \
- nextid.c ctx.c
+ nextid.c ctx.c cache.c
OBJS = init.lo tools.lo config.lo \
- add.lo bind.lo compare.lo delete.lo modify.lo search.lo \
- operational.lo \
+ add.lo bind.lo compare.lo delete.lo modify.lo modrdn.lo search.lo \
+ extended.lo operational.lo \
attr.lo index.lo key.lo filterindex.lo \
dn2entry.lo dn2id.lo id2entry.lo idl.lo \
- nextid.lo ctx.lo
+ nextid.lo ctx.lo cache.lo
LDAP_INCDIR= ../../../include
LDAP_LIBDIR= ../../../libraries
size_t textlen = sizeof textbuf;
AttributeDescription *children = slap_schema.si_ad_children;
AttributeDescription *entry = slap_schema.si_ad_entry;
- ID eid;
- int num_retries = 0;
- int success;
+ ID eid = NOID;
LDAPControl **postread_ctrl = NULL;
LDAPControl *ctrls[SLAP_MAX_RESPONSE_CONTROLS];
int num_ctrls = 0;
wt_ctx *wc;
Entry *e = NULL;
Entry *p = NULL;
- ID pid;
+ ID pid = NOID;
int rc;
- Debug( LDAP_DEBUG_ARGS, "==> " LDAP_XSTRING(wt_add) ": %s\n",
- op->ora_e->e_name.bv_val );
+ Debug( LDAP_DEBUG_ARGS, "==> wt_add: %s\n", op->ora_e->e_name.bv_val );
ctrls[num_ctrls] = 0;
get_relax(op), 1, NULL, &rs->sr_text, textbuf, textlen );
if ( rs->sr_err != LDAP_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE,
- LDAP_XSTRING(wt_add)
- ": entry failed schema check: %s (%d)\n",
+ "wt_add: entry failed schema check: %s (%d)\n",
rs->sr_text, rs->sr_err );
goto return_results;
}
rs->sr_err = slap_add_opattrs( op, &rs->sr_text, textbuf, textlen, 1 );
if ( rs->sr_err != LDAP_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE,
- LDAP_XSTRING(wt_add)
- ": entry failed op attrs add: %s (%d)\n",
+ "wt_add: entry failed op attrs add: %s (%d)\n",
rs->sr_text, rs->sr_err );
goto return_results;
}
wc = wt_ctx_get(op, wi);
if( !wc ){
- Debug( LDAP_DEBUG_ANY,
- LDAP_XSTRING(wt_add)
- ": wt_ctx_get failed\n" );
+ Debug( LDAP_DEBUG_ANY, "wt_add: wt_ctx_get failed\n" );
rs->sr_err = LDAP_OTHER;
rs->sr_text = "internal error";
send_ldap_result( op, rs );
default:
/* TODO: retry handling */
Debug( LDAP_DEBUG_ANY,
- LDAP_XSTRING(wt_add)
- ": error at wt_dn2entry() rc=%d\n",
- rc );
+ "wt_add: error at wt_dn2entry() rc=%d\n", rc );
rs->sr_err = LDAP_OTHER;
rs->sr_text = "internal error";
goto return_results;
break;
default:
Debug( LDAP_DEBUG_ANY,
- LDAP_XSTRING(wt_add)
- ": error at wt_dn2pentry() rc=%d\n",
- rc );
+ "wt_add: error at wt_dn2pentry() rc=%d\n", rc );
rs->sr_err = LDAP_OTHER;
rs->sr_text = "internal error";
goto return_results;
rs->sr_ref = NULL;
}
p = NULL;
- Debug( LDAP_DEBUG_TRACE,
- LDAP_XSTRING(wt_add) ": parent "
- "does not exist\n" );
+ Debug( LDAP_DEBUG_TRACE, "wt_add: parent does not exist\n" );
rs->sr_err = LDAP_REFERRAL;
rs->sr_flags = REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED;
goto return_results;
*/
p = NULL;
- Debug( LDAP_DEBUG_TRACE,
- LDAP_XSTRING(wt_add) ": no write access to parent\n" );
+ Debug( LDAP_DEBUG_TRACE, "wt_add: no write access to parent\n" );
rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
rs->sr_text = "no write access to parent";
goto return_results;;
wt_entry_return( p );
p = NULL;
/* parent is a subentry, don't allow add */
- Debug( LDAP_DEBUG_TRACE,
- LDAP_XSTRING(wt_add) ": parent is subentry\n" );
+ Debug( LDAP_DEBUG_TRACE, "wt_add: parent is subentry\n" );
rs->sr_err = LDAP_OBJECT_CLASS_VIOLATION;
rs->sr_text = "parent is a subentry";
goto return_results;;
wt_entry_return( p );
p = NULL;
/* parent is an alias, don't allow add */
- Debug( LDAP_DEBUG_TRACE,
- LDAP_XSTRING(wt_add) ": parent is alias\n" );
+ Debug( LDAP_DEBUG_TRACE, "wt_add: parent is alias\n" );
rs->sr_err = LDAP_ALIAS_PROBLEM;
rs->sr_text = "parent is an alias";
goto return_results;;
ber_bvarray_free( ref );
wt_entry_return( p );
p = NULL;
- Debug( LDAP_DEBUG_TRACE,
- LDAP_XSTRING(wt_add) ": parent is referral\n" );
+ Debug( LDAP_DEBUG_TRACE, "wt_add: parent is referral\n" );
rs->sr_err = LDAP_REFERRAL;
rs->sr_flags = REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED;
entry, NULL, ACL_WADD, NULL );
if ( ! rs->sr_err ) {
- Debug( LDAP_DEBUG_TRACE,
- LDAP_XSTRING(wt_add) ": no write access to entry\n" );
+ Debug( LDAP_DEBUG_TRACE, "wt_add: no write access to entry\n" );
rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
rs->sr_text = "no write access to entry";
goto return_results;
* Check ACL for attribute write access
*/
if (!acl_check_modlist(op, op->ora_e, op->ora_modlist)) {
- Debug( LDAP_DEBUG_TRACE,
- LDAP_XSTRING(wt_add) ": no write access to attribute\n" );
+ Debug( LDAP_DEBUG_TRACE, "wt_add: no write access to attribute\n" );
rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
rs->sr_text = "no write access to attribute";
goto return_results;
}
- rc = wc->session->begin_transaction(wc->session, NULL);
+ rc = wc->session->begin_transaction(wc->session, "isolation=read-uncommitted");
if( rc ) {
- Debug( LDAP_DEBUG_TRACE,
- LDAP_XSTRING(wt_add) ": begin_transaction failed: %s (%d)\n",
+ Debug( LDAP_DEBUG_TRACE, "wt_add: begin_transaction failed: %s (%d)\n",
wiredtiger_strerror(rc), rc );
rs->sr_err = LDAP_OTHER;
rs->sr_text = "begin_transaction failed";
goto return_results;
}
- Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(wt_add) ": session id: %p\n",
- wc->session );
+ Debug( LDAP_DEBUG_TRACE, "wt_add: session id: %p\n", wc->session );
wt_next_id( op->o_bd, &eid );
op->ora_e->e_id = eid;
- rc = wt_dn2id_add( op, wc->session, pid, op->ora_e );
+ rc = wt_dn2id_add( op, wc, pid, op->ora_e );
if( rc ){
Debug( LDAP_DEBUG_TRACE,
- LDAP_XSTRING(wt_add)
- ": dn2id_add failed: %s (%d)\n",
+ "wt_add: dn2id_add failed: %s (%d)\n",
wiredtiger_strerror(rc), rc );
switch( rc ) {
case WT_DUPLICATE_KEY:
goto return_results;
}
- rc = wt_id2entry_add( op, wc->session, op->ora_e );
+ rc = wt_id2entry_add( op, wc, op->ora_e );
if ( rc ) {
Debug( LDAP_DEBUG_TRACE,
- LDAP_XSTRING(wt_add)
- ": id2entry_add failed: %s (%d)\n",
+ "wt_add: id2entry_add failed: %s (%d)\n",
wiredtiger_strerror(rc), rc );
if ( rc == LDAP_ADMINLIMIT_EXCEEDED ) {
rs->sr_err = LDAP_ADMINLIMIT_EXCEEDED;
rc = wt_index_entry_add( op, wc, op->ora_e );
if ( rc ) {
Debug(LDAP_DEBUG_TRACE,
- "<== " LDAP_XSTRING(wt_add)
- ": index add failed: %s (%d)\n",
+ "<== wt_add: index add failed: %s (%d)\n",
wiredtiger_strerror(rc), rc );
rs->sr_err = LDAP_OTHER;
rs->sr_text = "index add failed";
rc = wc->session->commit_transaction(wc->session, NULL);
if( rc ) {
Debug( LDAP_DEBUG_TRACE,
- "<== " LDAP_XSTRING(wt_add)
- ": commit_transaction failed: %s (%d)\n",
+ "<== wt_add: commit_transaction failed: %s (%d)\n",
wiredtiger_strerror(rc), rc );
rs->sr_err = LDAP_OTHER;
rs->sr_text = "commit_transaction failed";
if ( slap_read_controls( op, rs, op->ora_e,
&slap_post_read_bv, postread_ctrl ) )
{
- Debug( LDAP_DEBUG_TRACE,
- "<=- " LDAP_XSTRING(wt_add) ": post-read "
- "failed!\n" );
+ Debug( LDAP_DEBUG_TRACE, "<=- wt_add: post-read failed!\n" );
if ( op->o_postread & SLAP_CONTROL_CRITICAL ) {
/* FIXME: is it correct to abort
* operation if control fails? */
}
Debug(LDAP_DEBUG_TRACE,
- LDAP_XSTRING(wt_add) ": added%s id=%08lx dn=\"%s\"\n",
+ "wt_add: added%s id=%08lx dn=\"%s\"\n",
op->o_noop ? " (no-op)" : "",
op->ora_e->e_id, op->ora_e->e_dn );
return_results:
- success = rs->sr_err;
send_ldap_result( op, rs );
slap_graduate_commit_csn( op );
#include "back-wt.h"
#include "slap-config.h"
+#include "lutil.h"
/* Find the ad, return -1 if not found,
* set point for insertion if ins is non-NULL
static int
ainfo_insert( struct wt_info *wi, AttrInfo *a )
{
- int x;
+ int x = INT_MAX;
int i = wt_attr_slot( wi, a->ai_desc, &x );
/* Is it a dup? */
return rc;
}
+static int
+wt_attr_index_unparser( void *v1, void *v2 )
+{
+ AttrInfo *ai = v1;
+ BerVarray *bva = v2;
+ struct berval bv;
+ char *ptr;
+
+ slap_index2bvlen( ai->ai_indexmask, &bv );
+ if ( bv.bv_len ) {
+ bv.bv_len += ai->ai_desc->ad_cname.bv_len + 1;
+ ptr = ch_malloc( bv.bv_len+1 );
+ bv.bv_val = lutil_strcopy(ptr,
+ (const char*)ai->ai_desc->ad_cname.bv_val );
+ *bv.bv_val++ = ' ';
+ slap_index2bv( ai->ai_indexmask, &bv );
+ bv.bv_val = ptr;
+ ber_bvarray_add( bva, &bv );
+ }
+ return 0;
+}
+
+static AttributeDescription addef = { NULL, NULL, BER_BVC("default") };
+static AttrInfo aidef = { &addef };
+
+void
+wt_attr_index_unparse( struct wt_info *wi, BerVarray *bva )
+{
+ int i;
+
+ if ( wi->wi_defaultmask ) {
+ aidef.ai_indexmask = wi->wi_defaultmask;
+ wt_attr_index_unparser( &aidef, bva );
+ }
+ for ( i=0; i<wi->wi_nattrs; i++ )
+ wt_attr_index_unparser( wi->wi_attrs[i], bva );
+}
+
void
wt_attr_info_free( AttrInfo *ai )
{
free( wi->wi_attrs );
}
-
-
/*
* Local variables:
* indent-tabs-mode: t
/* The default search IDL stack cache depth */
#define DEFAULT_SEARCH_STACK_DEPTH 16
+#define WT_CONFIG_MAX 2048
+
struct wt_info {
WT_CONNECTION *wi_conn;
- char *wi_dbenv_home;
- char *wi_dbenv_config;
+ WT_CONNECTION *wi_cache;
+ char *wi_home;
+ char *wi_config;
ID wi_lastid;
slap_mask_t wi_defaultmask;
#define WT_DEL_INDEX 0x08
#define WT_RE_OPEN 0x10
#define WT_NEED_UPGRADE 0x20
+#define WT_USE_IDLCACHE 0x40
};
#define WT_TABLE_ID2ENTRY "table:id2entry"
#define WT_TABLE_DN2ID "table:dn2id"
#define WT_INDEX_DN "index:id2entry:dn"
+#define WT_INDEX_NDN "index:dn2id:ndn"
#define WT_INDEX_PID "index:dn2id:pid"
+/* Currently, revdn is primary key, the revdn index is obsolete. */
#define WT_INDEX_REVDN "index:dn2id:revdn"
+/* table for cache */
+#define WT_TABLE_IDLCACHE "table:idlcache"
+
#define ITEMzero(item) (memset((item), 0, sizeof(WT_ITEM)))
#define ITEM2bv(item,bv) ((bv)->bv_val = (item)->data, \
(bv)->bv_len = (item)->size)
#define bv2ITEM(bv,item) ((item)->data = (bv)->bv_val, \
(item)->size = (bv)->bv_len )
+#define WT_INDEX_CACHE_SIZE 1024
+
typedef struct {
WT_SESSION *session;
+ int is_begin_transaction;
+ WT_CURSOR *dn2id;
+ WT_CURSOR *dn2id_w;
+ WT_CURSOR *dn2id_ndn;
+ WT_CURSOR *dn2entry;
+ WT_CURSOR *id2entry;
+ WT_CURSOR *id2entry_add;
+ WT_CURSOR *id2entry_update;
+ WT_SESSION *idlcache_session;
+ WT_CURSOR *index_pid;
} wt_ctx;
/* for the cache of attribute information (which are indexed, etc.) */
wt_bind( Operation *op, SlapReply *rs )
{
struct wt_info *wi = (struct wt_info *) op->o_bd->be_private;
- WT_SESSION *session;
wt_ctx *wc;
int rc;
Entry *e = NULL;
Attribute *a;
AttributeDescription *password = slap_schema.si_ad_userPassword;
- Debug( LDAP_DEBUG_ARGS,
- "==> " LDAP_XSTRING(wt_bind) ": dn: %s\n",
+ Debug( LDAP_DEBUG_ARGS, "==> wt_bind: dn: %s\n",
op->o_req_dn.bv_val );
/* allow noauth binds */
wc = wt_ctx_get(op, wi);
if( !wc ){
Debug( LDAP_DEBUG_ANY,
- LDAP_XSTRING(wt_bind)
- ": wt_ctx_get failed\n" );
+ "wt_bind: wt_ctx_get failed\n" );
rs->sr_err = LDAP_OTHER;
rs->sr_text = "internal error";
send_ldap_result( op, rs );
--- /dev/null
+/* OpenLDAP WiredTiger backend */
+/* $OpenLDAP$ */
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
+ *
+ * Copyright 2002-2017 The OpenLDAP Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted only as authorized by the OpenLDAP
+ * Public License.
+ *
+ * A copy of this license is available in the file LICENSE in the
+ * top-level directory of the distribution or, alternatively, at
+ * <http://www.OpenLDAP.org/license.html>.
+ */
+/* ACKNOWLEDGEMENTS:
+ * This work was developed by HAMANO Tsukasa <hamano@osstech.co.jp>
+ * based on back-bdb for inclusion in OpenLDAP Software.
+ * WiredTiger is a product of MongoDB Inc.
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+#include <ac/string.h>
+#include "back-wt.h"
+#include "slap-config.h"
+#include "idl.h"
+
+int wt_idlcache_get(wt_ctx *wc, struct berval *ndn, int scope, ID *ids)
+{
+ int rc = 0;
+ WT_ITEM item;
+ WT_SESSION *session = wc->idlcache_session;
+ WT_CURSOR *cursor = NULL;
+
+ Debug( LDAP_DEBUG_TRACE,
+ "=> wt_idlcache_get(\"%s\", %d)\n",
+ ndn->bv_val, scope );
+
+ rc = session->open_cursor(session, WT_TABLE_IDLCACHE, NULL,
+ NULL, &cursor);
+ if(rc){
+ Debug( LDAP_DEBUG_ANY,
+ "wt_idlcache_get: open_cursor failed: %s (%d)\n",
+ wiredtiger_strerror(rc), rc );
+ return rc;
+ }
+ cursor->set_key(cursor, ndn->bv_val, (int8_t)scope);
+ rc = cursor->search(cursor);
+ switch( rc ){
+ case 0:
+ break;
+ case WT_NOTFOUND:
+ Debug(LDAP_DEBUG_TRACE, "<= wt_idlcache_get: miss\n" );
+ goto done;
+ default:
+ Debug( LDAP_DEBUG_ANY, "<= wt_idlcache_get: search failed: %s (%d)\n",
+ wiredtiger_strerror(rc), rc );
+ rc = 0;
+ goto done;
+ }
+ rc = cursor->get_value(cursor, &item);
+ if (rc) {
+ Debug( LDAP_DEBUG_ANY,
+ "wt_idlcache_get: get_value failed: %s (%d)\n",
+ wiredtiger_strerror(rc), rc );
+ goto done;
+ }
+ if (item.size == 0) {
+ Debug(LDAP_DEBUG_TRACE, "<= wt_idlcache_get: updating\n");
+ rc = WT_NOTFOUND;
+ goto done;
+ }
+ memcpy(ids, item.data, item.size);
+
+ Debug(LDAP_DEBUG_TRACE,
+ "<= wt_idlcache_get: hit id=%ld first=%ld last=%ld\n",
+ (long)ids[0],
+ (long)WT_IDL_FIRST(ids),
+ (long)WT_IDL_LAST(ids));
+done:
+ if(cursor) {
+ cursor->close(cursor);
+ }
+ return rc;
+}
+
+int wt_idlcache_set(wt_ctx *wc, struct berval *ndn, int scope, ID *ids)
+{
+ int rc = 0;
+ WT_ITEM item;
+ WT_SESSION *session = wc->idlcache_session;
+ WT_CURSOR *cursor = NULL;
+
+ Debug( LDAP_DEBUG_TRACE,
+ "=> wt_idlcache_set(\"%s\", %d)\n",
+ ndn->bv_val, scope );
+
+ item.size = WT_IDL_SIZEOF(ids);
+ item.data = ids;
+
+ rc = session->open_cursor(session, WT_TABLE_IDLCACHE, NULL,
+ "overwrite=false", &cursor);
+ if(rc){
+ Debug( LDAP_DEBUG_ANY,
+ "wt_idlcache_set: open_cursor failed: %s (%d)\n",
+ wiredtiger_strerror(rc), rc );
+ return rc;
+ }
+ cursor->set_key(cursor, ndn->bv_val, (int8_t)scope);
+ cursor->set_value(cursor, &item);
+ rc = cursor->update(cursor);
+ switch( rc ){
+ case 0:
+ break;
+ case WT_NOTFOUND:
+ // updating cache by another thread
+ goto done;
+ default:
+ Debug( LDAP_DEBUG_ANY,
+ "wt_idlcache_set: update failed: %s (%d)\n",
+ wiredtiger_strerror(rc), rc );
+ goto done;
+ }
+
+ Debug(LDAP_DEBUG_TRACE,
+ "<= wt_idlcache_set: set idl size=%ld\n",
+ (long)ids[0]);
+done:
+ if(cursor) {
+ cursor->close(cursor);
+ }
+ return rc;
+}
+
+int wt_idlcache_begin(wt_ctx *wc, struct berval *ndn, int scope)
+{
+ int rc = 0;
+ WT_ITEM item;
+ WT_SESSION *session = wc->idlcache_session;
+ WT_CURSOR *cursor = NULL;
+
+ Debug( LDAP_DEBUG_TRACE,
+ "=> wt_idlcache_begin(\"%s\", %d)\n",
+ ndn->bv_val, scope );
+
+ item.size = 0;
+ item.data = "";
+
+ rc = session->open_cursor(session, WT_TABLE_IDLCACHE, NULL,
+ "overwrite=true", &cursor);
+ if(rc){
+ Debug( LDAP_DEBUG_ANY,
+ "wt_idlcache_begin: open_cursor failed: %s (%d)\n",
+ wiredtiger_strerror(rc), rc );
+ return rc;
+ }
+ cursor->set_key(cursor, ndn->bv_val, (int8_t)scope);
+ cursor->set_value(cursor, &item);
+ rc = cursor->update(cursor);
+ if(rc){
+ Debug( LDAP_DEBUG_ANY,
+ "wt_idlcache_begin: update failed: %s (%d)\n",
+ wiredtiger_strerror(rc), rc );
+ goto done;
+ }
+
+ Debug(LDAP_DEBUG_TRACE,
+ "<= wt_idlcache_begin: set updating\n" );
+
+done:
+ if(cursor) {
+ cursor->close(cursor);
+ }
+ return rc;
+}
+
+int wt_idlcache_clear(Operation *op, wt_ctx *wc, struct berval *ndn)
+{
+ BackendDB *be = op->o_bd;
+ int rc = 0;
+ struct berval pdn = *ndn;
+ WT_SESSION *session = wc->idlcache_session;
+ WT_CURSOR *cursor = NULL;
+ int level = 0;
+
+ Debug( LDAP_DEBUG_TRACE,
+ "=> wt_idlcache_clear(\"%s\")\n",
+ ndn->bv_val );
+
+ if (be_issuffix( be, ndn )) {
+ return 0;
+ }
+
+ rc = session->open_cursor(session, WT_TABLE_IDLCACHE, NULL,
+ NULL, &cursor);
+ if(rc){
+ Debug( LDAP_DEBUG_ANY,
+ "wt_idlcache_clear: open_cursor failed: %s (%d)\n",
+ wiredtiger_strerror(rc), rc );
+ return rc;
+ }
+
+ do {
+ dnParent( &pdn, &pdn );
+ if (level == 0) {
+ /* clear only parent level cache */
+ cursor->set_key(cursor, pdn.bv_val, (int8_t)LDAP_SCOPE_ONE);
+ cursor->remove(cursor);
+ }
+ cursor->set_key(cursor, pdn.bv_val, (int8_t)LDAP_SCOPE_SUB);
+ cursor->remove(cursor);
+ cursor->set_key(cursor, pdn.bv_val, (int8_t)LDAP_SCOPE_CHILDREN);
+ cursor->remove(cursor);
+ level++;
+ }while(!be_issuffix( be, &pdn ));
+
+ if(cursor) {
+ cursor->close(cursor);
+ }
+ return 0;
+}
+
+/*
+ * Local variables:
+ * indent-tabs-mode: t
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ */
int rc;
wt_ctx *wc = NULL;
- Debug( LDAP_DEBUG_ARGS, "==> " LDAP_XSTRING(wt_compare) ": %s\n",
+ Debug( LDAP_DEBUG_ARGS, "==> wt_compare: %s\n",
op->o_req_dn.bv_val );
wc = wt_ctx_get(op, wi);
if( !wc ){
- Debug( LDAP_DEBUG_ANY,
- LDAP_XSTRING(wt_compare)
- ": wt_ctx_get failed\n" );
+ Debug( LDAP_DEBUG_ANY, "wt_compare: wt_ctx_get failed\n" );
rs->sr_err = LDAP_OTHER;
rs->sr_text = "internal error";
send_ldap_result( op, rs );
return rs->sr_err;
}
- rs->sr_err = wt_dn2entry(op->o_bd, wc, &op->o_req_ndn, &e);
- switch( rs->sr_err ) {
+ rc = wt_dn2entry(op->o_bd, wc, &op->o_req_ndn, &e);
+ switch( rc ) {
case 0:
case WT_NOTFOUND:
break;
goto return_results;
}
- if ( rs->sr_err == WT_NOTFOUND ) {
- if ( e != NULL ) {
- /* return referral only if "disclose" is granted on the object */
- if ( ! access_allowed( op, e, slap_schema.si_ad_entry,
- NULL, ACL_DISCLOSE, NULL ) )
- {
+ if ( rc == WT_NOTFOUND ||
+ (!manageDSAit && e && is_entry_glue( e ) )) {
+
+ if ( !e ) {
+ rc = wt_dn2aentry(op->o_bd, wc, &op->o_req_ndn, &e);
+ switch( rc ) {
+ case 0:
+ break;
+ case WT_NOTFOUND:
rs->sr_err = LDAP_NO_SUCH_OBJECT;
- } else {
- rs->sr_matched = ch_strdup( e->e_dn );
- if ( is_entry_referral( e )) {
- BerVarray ref = get_entry_referrals( op, e );
- rs->sr_ref = referral_rewrite( ref,
- &e->e_name,
- &op->o_req_dn,
- LDAP_SCOPE_DEFAULT );
- ber_bvarray_free( ref );
- } else {
- rs->sr_ref = NULL;
- }
- rs->sr_err = LDAP_REFERRAL;
+ goto return_results;
+ default:
+ Debug( LDAP_DEBUG_ANY, "wt_compare: wt_dn2aentry failed (%d)\n",
+ rc );
+ rs->sr_err = LDAP_OTHER;
+ rs->sr_text = "internal error";
+ goto return_results;
}
- wt_entry_return( e );
- e = NULL;
- } else {
- rs->sr_ref = referral_rewrite( default_referral,
- NULL,
- &op->o_req_dn,
- LDAP_SCOPE_DEFAULT );
- rs->sr_err = rs->sr_ref ? LDAP_REFERRAL : LDAP_NO_SUCH_OBJECT;
}
+ /* return referral only if "disclose" is granted on the object */
+ if ( ! access_allowed( op, e, slap_schema.si_ad_entry,
+ NULL, ACL_DISCLOSE, NULL ) )
+ {
+ rs->sr_err = LDAP_NO_SUCH_OBJECT;
+ } else {
+ rs->sr_matched = ch_strdup( e->e_dn );
+ if ( is_entry_referral( e )) {
+ BerVarray ref = get_entry_referrals( op, e );
+ rs->sr_ref = referral_rewrite( ref,
+ &e->e_name,
+ &op->o_req_dn,
+ LDAP_SCOPE_DEFAULT );
+ ber_bvarray_free( ref );
+ } else {
+ rs->sr_ref = NULL;
+ }
+ rs->sr_err = LDAP_REFERRAL;
+ }
rs->sr_flags = REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED;
send_ldap_result( op, rs );
goto done;
WT_DIRECTORY = 1,
WT_CONFIG,
WT_INDEX,
+ WT_MODE,
+ WT_IDLCACHE,
};
static ConfigTable wtcfg[] = {
"DESC 'Directory for database content' "
"EQUALITY caseIgnoreMatch "
"SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
- { "wtconfig", "config", 2, 2, 0, ARG_STRING|ARG_MAGIC|WT_CONFIG,
- wt_cf_gen, "( OLcfgDbAt:13.1 NAME 'olcWtConfig' "
- "DESC 'Configuration for WiredTiger' "
- "EQUALITY caseIgnoreMatch "
- "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
{ "index", "attr> <[pres,eq,approx,sub]", 2, 3, 0, ARG_MAGIC|WT_INDEX,
wt_cf_gen, "( OLcfgDbAt:0.2 NAME 'olcDbIndex' "
"DESC 'Attribute index parameters' "
"EQUALITY caseIgnoreMatch "
"SYNTAX OMsDirectoryString )", NULL, NULL },
+ { "mode", "mode", 2, 2, 0, ARG_MAGIC|WT_MODE,
+ wt_cf_gen, "( OLcfgDbAt:0.3 NAME 'olcDbMode' "
+ "DESC 'Unix permissions of database files' "
+ "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
+ { "wtconfig", "config", 2, 2, 0, ARG_STRING|ARG_MAGIC|WT_CONFIG,
+ wt_cf_gen, "( OLcfgDbAt:13.1 NAME 'olcWtConfig' "
+ "DESC 'Configuration for WiredTiger' "
+ "EQUALITY caseIgnoreMatch "
+ "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
+ { "idlcache", NULL, 1, 2, 0, ARG_ON_OFF|ARG_MAGIC|WT_IDLCACHE,
+ wt_cf_gen, "( OLcfgDbAt:13.2 NAME 'olcIDLcache' "
+ "DESC 'enable IDL cache' "
+ "SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL },
{ NULL, NULL, 0, 0, 0, ARG_IGNORED,
NULL, NULL, NULL, NULL }
};
static ConfigOCs wtocs[] = {
- { "( OLcfgDbOc:9.1 "
+ { "( OLcfgDbOc:13.1 "
"NAME 'olcWtConfig' "
"DESC 'Wt backend configuration' "
"SUP olcDatabaseConfig "
"MUST olcDbDirectory "
- "MAY ( olcWtConfig $ olcDbIndex ) )",
+ "MAY ( olcWtConfig $ olcDbIndex $ olcDbMode $ olcIDLcache) )",
Cft_Database, wtcfg },
{ NULL, 0, NULL }
};
wt_online_index( void *ctx, void *arg )
{
// Not implement yet
+ return NULL;
}
/* Cleanup loose ends after Modify completes */
struct wt_info *wi = (struct wt_info *) c->be->be_private;
int rc;
- if(c->op == SLAP_CONFIG_EMIT) {
+ if( c->op == SLAP_CONFIG_EMIT ) {
+ rc = 0;
+ switch( c->type ) {
+ case WT_DIRECTORY:
+ if ( wi->wi_home ) {
+ c->value_string = ch_strdup( wi->wi_home );
+ } else {
+ rc = 1;
+ }
+ break;
+ case WT_INDEX:
+ wt_attr_index_unparse( wi, &c->rvalue_vals );
+ if ( !c->rvalue_vals ) rc = 1;
+ break;
+ case WT_IDLCACHE:
+ if ( wi->wi_flags & WT_USE_IDLCACHE) {
+ c->value_int = 1;
+ }
+ break;
+ }
+ return rc;
+ } else if ( c->op == LDAP_MOD_DELETE ) {
rc = 0;
- // not implement yet
return rc;
}
switch( c->type ) {
case WT_DIRECTORY:
- ch_free( wi->wi_dbenv_home );
- wi->wi_dbenv_home = c->value_string;
+ ch_free( wi->wi_home );
+ wi->wi_home = c->value_string;
break;
case WT_CONFIG:
- ch_free( wi->wi_dbenv_config );
- wi->wi_dbenv_config = c->value_string;
+ if(strlen(wi->wi_config) + 1 + strlen(c->value_string) > WT_CONFIG_MAX){
+ fprintf( stderr, "%s: "
+ "\"wtconfig\" are too long. Increase WT_CONFIG_MAX or you may realloc the buffer.\n",
+ c->log );
+ return 1;
+ }
+ /* size of wi->wi_config is WT_CONFIG_MAX + 1, it's guaranteed with NUL-terminate. */
+ strcat(wi->wi_config, ",");
+ strcat(wi->wi_config, c->value_string);
break;
case WT_INDEX:
}
break;
+ case WT_MODE:
+ fprintf( stderr, "%s: "
+ "back-wt does not support \"mode\" option. use umask instead.\n",
+ c->log );
+ return 1;
+
+ case WT_IDLCACHE:
+ if ( c->value_int ) {
+ wi->wi_flags |= WT_USE_IDLCACHE;
+ } else {
+ wi->wi_flags &= ~WT_USE_IDLCACHE;
+ }
+ break;
}
return LDAP_SUCCESS;
}
wc = ch_malloc( sizeof( wt_ctx ) );
if( !wc ) {
- Debug( LDAP_DEBUG_ANY,
- LDAP_XSTRING(wt_ctx_init)
- ": cannot allocate memory\n" );
+ Debug( LDAP_DEBUG_ANY, "wt_ctx_init: cannot allocate memory\n" );
return NULL;
}
memset(wc, 0, sizeof(wt_ctx));
- if(!wc->session){
- rc = wi->wi_conn->open_session(wi->wi_conn, NULL, NULL, &wc->session);
- if( rc ) {
- Debug( LDAP_DEBUG_ANY,
- LDAP_XSTRING(wt_ctx_session)
- ": open_session error %s(%d)\n",
- wiredtiger_strerror(rc), rc );
- return NULL;
- }
+ rc = wi->wi_conn->open_session(wi->wi_conn, NULL, NULL, &wc->session);
+ if( rc ) {
+ Debug( LDAP_DEBUG_ANY, "wt_ctx_init: open_session error %s(%d)\n",
+ wiredtiger_strerror(rc), rc );
+ return NULL;
+ }
+
+ /* readonly mode */
+ if (!wi->wi_cache) {
+ return wc;
+ }
+
+ rc = wi->wi_cache->open_session(wi->wi_cache, NULL, NULL, &wc->idlcache_session);
+ if( rc ) {
+ Debug( LDAP_DEBUG_ANY,
+ "wt_ctx_init: cannnot open idlcache session %s(%d)\n",
+ wiredtiger_strerror(rc), rc );
+ return NULL;
}
+
return wc;
}
wt_ctx *wc = data;
if(wc->session){
- wc->session->close(wc->session, NULL);
+ /*
+ * The session will close automatically when db closing.
+ * We can close session here, but it's require to check db
+ * status, otherwise it will cause SEGV.
+ */
+ /*
+ if(IS_DB_OPEN) {
+ wc->session->close(wc->session, NULL);
+ }
+ */
wc->session = NULL;
}
+
ch_free(wc);
}
wt_ctx *wc = NULL;
rc = ldap_pvt_thread_pool_getkey(op->o_threadctx,
- wt_ctx_get, &data, NULL );
+ wi, &data, NULL );
if( rc ){
wc = wt_ctx_init(wi);
if( !wc ) {
- Debug( LDAP_DEBUG_ANY,
- LDAP_XSTRING(wt_ctx)
- ": wt_ctx_init failed\n" );
+ Debug( LDAP_DEBUG_ANY, "wt_ctx: wt_ctx_init failed\n" );
return NULL;
}
rc = ldap_pvt_thread_pool_setkey( op->o_threadctx,
- wt_ctx_get, wc, wt_ctx_free,
+ wi, wc, wt_ctx_free,
NULL, NULL );
if( rc ) {
Debug( LDAP_DEBUG_ANY, "wt_ctx: setkey error(%d)\n",
return (wt_ctx *)data;
}
-WT_CURSOR *
-wt_ctx_index_cursor(wt_ctx *wc, struct berval *name, int create)
-{
- WT_CURSOR *cursor = NULL;
- WT_SESSION *session = wc->session;
- char tablename[1024];
- int rc;
-
- snprintf(tablename, sizeof(tablename), "table:%s", name->bv_val);
-
- rc = session->open_cursor(session, tablename, NULL,
- "overwrite=false", &cursor);
- if (rc == ENOENT && create) {
- rc = session->create(session,
- tablename,
- "key_format=uQ,"
- "value_format=x,"
- "columns=(key, id, none)");
- if( rc ) {
- Debug( LDAP_DEBUG_ANY,
- LDAP_XSTRING(indexer) ": table \"%s\": "
- "cannot create idnex table: %s (%d)\n",
- tablename, wiredtiger_strerror(rc), rc);
- return NULL;
- }
- rc = session->open_cursor(session, tablename, NULL,
- "overwrite=false", &cursor);
- }
- if ( rc ) {
- Debug( LDAP_DEBUG_ANY,
- LDAP_XSTRING(wt_id2entry_put)
- ": open cursor failed: %s (%d)\n",
- wiredtiger_strerror(rc), rc );
- return NULL;
- }
-
- return cursor;
-}
-
/*
* Local variables:
* indent-tabs-mode: t
wt_ctx *wc;
int rc;
- WT_CURSOR *cursor = NULL;
int parent_is_glue = 0;
int parent_is_leaf = 0;
- Debug( LDAP_DEBUG_ARGS, "==> " LDAP_XSTRING(wt_delete) ": %s\n",
+ Debug( LDAP_DEBUG_ARGS, "==> wt_delete: %s\n",
op->o_req_dn.bv_val );
if( op->o_txnSpec && txn_preop( op, rs ))
wc = wt_ctx_get(op, wi);
if( !wc ){
- Debug( LDAP_DEBUG_TRACE,
- LDAP_XSTRING(wt_delete)
- ": wt_ctx_get failed\n" );
+ Debug( LDAP_DEBUG_TRACE, "wt_delete: wt_ctx_get failed\n" );
rs->sr_err = LDAP_OTHER;
rs->sr_text = "internal error";
goto return_results;
case WT_NOTFOUND:
break;
default:
- /* TODO: error handling */
rs->sr_err = LDAP_OTHER;
rs->sr_text = "internal error";
Debug( LDAP_DEBUG_ANY,
- LDAP_XSTRING(wt_delete)
- ": error at wt_dn2entry() rc=%d\n",
- rc );
+ "wt_delete: error at wt_dn2entry() rc=%d\n", rc );
goto return_results;
}
if ( rc == WT_NOTFOUND && pdn.bv_len != 0 ) {
Debug( LDAP_DEBUG_ARGS,
- "<== " LDAP_XSTRING(wt_delete) ": no such object %s\n",
- op->o_req_dn.bv_val );
-
- if ( p && !BER_BVISEMPTY( &p->e_name )) {
- rs->sr_matched = ch_strdup( p->e_name.bv_val );
- if ( is_entry_referral( p )) {
- BerVarray ref = get_entry_referrals( op, p );
- rs->sr_ref = referral_rewrite( ref, &p->e_name,
+ "<== wt_delete: parent not found %s\n", op->o_req_dn.bv_val );
+ rc = wt_dn2aentry(op->o_bd, wc, &op->o_req_ndn, &e);
+ Debug( LDAP_DEBUG_ARGS, "<== wt_delete: rc=%d\n", rc );
+
+ switch( rc ) {
+ case 0:
+ break;
+ case WT_NOTFOUND:
+ rs->sr_err = LDAP_NO_SUCH_OBJECT;
+ goto return_results;
+ default:
+ Debug( LDAP_DEBUG_ANY, "wt_delete: wt_dn2aentry failed (%d)\n", rc );
+ rs->sr_err = LDAP_OTHER;
+ rs->sr_text = "internal error";
+ goto return_results;
+ }
+
+ if ( e && !BER_BVISEMPTY( &e->e_name )) {
+ rs->sr_matched = ch_strdup( e->e_name.bv_val );
+ if ( is_entry_referral( e )) {
+ BerVarray ref = get_entry_referrals( op, e );
+ rs->sr_ref = referral_rewrite( ref, &e->e_name,
&op->o_req_dn, LDAP_SCOPE_DEFAULT );
ber_bvarray_free( ref );
} else {
case 0:
break;
case WT_NOTFOUND:
- Debug( LDAP_DEBUG_ARGS,
- "<== " LDAP_XSTRING(wt_delete)
- ": no such object %s\n",
- op->o_req_dn.bv_val );
- rs->sr_err = LDAP_REFERRAL;
- rs->sr_flags = REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED;
- goto return_results;
+ break;
default:
- /* TODO: error handling */
rs->sr_err = LDAP_OTHER;
rs->sr_text = "internal error";
Debug( LDAP_DEBUG_ANY,
- LDAP_XSTRING(wt_delete)
- ": error at wt_dn2entry() rc=%d\n",
- rc );
+ "wt_delete: error at wt_dn2entry() rc=%d\n", rc );
goto return_results;
}
/* FIXME : dn2entry() should return non-glue entry */
- if ( !manageDSAit && is_entry_glue( e ) ) {
- Debug( LDAP_DEBUG_ARGS,
- "<== " LDAP_XSTRING(wt_delete)
- ": glue entry %s\n",
- op->o_req_dn.bv_val );
+ if (rc == WT_NOTFOUND ||
+ ( !manageDSAit && e && is_entry_glue( e ) )) {
+ if ( !e ) {
+ Debug( LDAP_DEBUG_ARGS,
+ "<== wt_delete: no such object %s\n",
+ op->o_req_dn.bv_val);
+ rc = wt_dn2aentry(op->o_bd, wc, &op->o_req_ndn, &e);
+ switch( rc ) {
+ case 0:
+ break;
+ case WT_NOTFOUND:
+ rs->sr_err = LDAP_NO_SUCH_OBJECT;
+ goto return_results;
+ default:
+ Debug( LDAP_DEBUG_ANY, "wt_delete: wt_dn2aentry failed (%d)\n", rc );
+ rs->sr_err = LDAP_OTHER;
+ rs->sr_text = "internal error";
+ goto return_results;
+ }
+ }
rs->sr_matched = ch_strdup( e->e_dn );
if ( is_entry_referral( e )) {
if ( !rs->sr_err ) {
Debug( LDAP_DEBUG_TRACE,
- "<== " LDAP_XSTRING(wt_delete) ": no write "
- "access to parent\n" );
+ "<== wt_delete: no write access to parent\n" );
rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
rs->sr_text = "no write access to parent";
goto return_results;
if ( !rs->sr_err ) {
Debug( LDAP_DEBUG_TRACE,
- "<== " LDAP_XSTRING(wt_delete)
- ": no access to parent\n" );
+ "<== wt_delete: no access to parent\n" );
rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
rs->sr_text = "no write access to parent";
goto return_results;
} else {
Debug( LDAP_DEBUG_TRACE,
- "<== " LDAP_XSTRING(wt_delete)
- ": no parent and not root\n" );
+ "<== wt_delete: no parent and not root\n" );
rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
goto return_results;
}
entry, NULL, ACL_WDEL, NULL );
if ( !rs->sr_err ) {
Debug( LDAP_DEBUG_TRACE,
- "<== " LDAP_XSTRING(wt_delete) ": no write access "
- "to entry\n" );
+ "<== wt_delete: no write access to entry\n" );
rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
rs->sr_text = "no write access to entry";
goto return_results;
/* entry is a referral, don't allow delete */
rs->sr_ref = get_entry_referrals( op, e );
- Debug( LDAP_DEBUG_TRACE,
- LDAP_XSTRING(tw_delete) ": entry is referral\n" );
+ Debug( LDAP_DEBUG_TRACE, "wt_delete: entry is referral\n" );
rs->sr_err = LDAP_REFERRAL;
rs->sr_matched = ch_strdup( e->e_name.bv_val );
&slap_pre_read_bv, preread_ctrl ) )
{
Debug( LDAP_DEBUG_TRACE,
- "<== " LDAP_XSTRING(wt_delete) ": pre-read "
- "failed!\n" );
+ "<== wt_delete: pre-read failed!\n" );
if ( op->o_preread & SLAP_CONTROL_CRITICAL ) {
/* FIXME: is it correct to abort
* operation if control fails? */
}
/* Can't do it if we have kids */
- rc = wt_dn2id_has_children( op, wc->session, e->e_id );
+ rc = wt_dn2id_has_children( op, wc, e->e_id );
if( rc != WT_NOTFOUND ) {
switch( rc ) {
case 0:
Debug(LDAP_DEBUG_ARGS,
- "<== " LDAP_XSTRING(wt_delete)
- ": non-leaf %s\n",
- op->o_req_dn.bv_val );
+ "<== wt_delete: non-leaf %s\n", op->o_req_dn.bv_val );
rs->sr_err = LDAP_NOT_ALLOWED_ON_NONLEAF;
rs->sr_text = "subordinate objects must be deleted first";
break;
default:
Debug(LDAP_DEBUG_ARGS,
- "<== " LDAP_XSTRING(wt_delete)
- ": has_children failed: %s (%d)\n",
+ "<== wt_delete: has_children failed: %s (%d)\n",
wiredtiger_strerror(rc), rc );
rs->sr_err = LDAP_OTHER;
rs->sr_text = "internal error";
rc = wc->session->begin_transaction(wc->session, NULL);
if( rc ) {
Debug( LDAP_DEBUG_TRACE,
- LDAP_XSTRING(wt_add) ": begin_transaction failed: %s (%d)\n",
+ "wt_delete: begin_transaction failed: %s (%d)\n",
wiredtiger_strerror(rc), rc );
rs->sr_err = LDAP_OTHER;
rs->sr_text = "begin_transaction failed";
}
/* delete from dn2id */
- rc = wt_dn2id_delete( op, wc->session, &e->e_nname);
+ rc = wt_dn2id_delete( op, wc, &op->o_req_ndn);
if ( rc ) {
Debug(LDAP_DEBUG_TRACE,
- "<== " LDAP_XSTRING(wt_delete)
- ": dn2id failed: %s (%d)\n",
+ "<== wt_delete: dn2id failed: %s (%d)\n",
wiredtiger_strerror(rc), rc );
rs->sr_err = LDAP_OTHER;
rs->sr_text = "dn2id delete failed";
rc = wt_index_entry_del( op, wc, e );
if ( rc ) {
Debug(LDAP_DEBUG_TRACE,
- "<== " LDAP_XSTRING(wt_delete)
- ": index delete failed: %s (%d)\n",
+ "<== wt_delete: index delete failed: %s (%d)\n",
wiredtiger_strerror(rc), rc );
rs->sr_err = LDAP_OTHER;
rs->sr_text = "index delete failed";
assert( !BER_BVISNULL( &op->o_csn ) );
vals[0] = op->o_csn;
BER_BVZERO( &vals[1] );
- rs->sr_err = wt_index_values( op, wc->session, slap_schema.si_ad_entryCSN,
+ rs->sr_err = wt_index_values( op, wc, slap_schema.si_ad_entryCSN,
vals, 0, SLAP_INDEX_ADD_OP );
if ( rs->sr_err != LDAP_SUCCESS ) {
rs->sr_text = "entryCSN index update failed";
}
/* delete from id2entry */
- rc = wt_id2entry_delete( op, wc->session, e );
+ rc = wt_id2entry_delete( op, wc, e );
if ( rc ) {
Debug( LDAP_DEBUG_TRACE,
- "<== " LDAP_XSTRING(wt_delete)
- ": id2entry failed: %s (%d)\n",
+ "<== wt_delete: id2entry failed: %s (%d)\n",
wiredtiger_strerror(rc), rc );
rs->sr_err = LDAP_OTHER;
rs->sr_text = "entry delete failed";
rc = wc->session->commit_transaction(wc->session, NULL);
if( rc ) {
Debug( LDAP_DEBUG_TRACE,
- "<== " LDAP_XSTRING(wt_delete)
- ": commit_transaction failed: %s (%d)\n",
+ "<== wt_delete: commit_transaction failed: %s (%d)\n",
wiredtiger_strerror(rc), rc );
rs->sr_err = LDAP_OTHER;
rs->sr_text = "commit_transaction failed";
}
Debug( LDAP_DEBUG_TRACE,
- LDAP_XSTRING(wt_delete)
- ": deleted%s id=%08lx dn=\"%s\"\n",
+ "wt_delete: deleted%s id=%08lx dn=\"%s\"\n",
op->o_noop ? " (no-op)" : "", e->e_id, op->o_req_dn.bv_val );
rs->sr_err = LDAP_SUCCESS;
struct berval *ndn,
Entry **ep ){
uint64_t id;
- WT_CURSOR *cursor = NULL;
WT_ITEM item;
EntryHeader eh;
int rc;
int eoff;
Entry *e = NULL;
WT_SESSION *session = wc->session;
+ WT_CURSOR *cursor = wc->dn2entry;
if( ndn->bv_len == 0 ){
- /* parent of root dn */
- return WT_NOTFOUND;
+ /* empty dn */
+ e = entry_alloc();
+ ber_dupbv(&e->e_nname, ndn);
+ *ep = e;
+ return LDAP_SUCCESS;
}
- rc = session->open_cursor(session,
- WT_INDEX_DN"(id, entry)",
- NULL, NULL, &cursor);
- if ( rc ) {
- Debug( LDAP_DEBUG_ANY,
- LDAP_XSTRING(wt_dn2entry)
- ": open_cursor failed: %s (%d)\n",
- wiredtiger_strerror(rc), rc );
- goto done;
+ if(!cursor){
+ rc = session->open_cursor(session,
+ WT_INDEX_DN"(id, entry)",
+ NULL, NULL, &cursor);
+ if ( rc ) {
+ Debug( LDAP_DEBUG_ANY,
+ "wt_dn2entry: open_cursor failed: %s (%d)\n",
+ wiredtiger_strerror(rc), rc );
+ goto done;
+ }
+ wc->dn2entry = cursor;
}
cursor->set_key(cursor, ndn->bv_val);
goto done;
default:
Debug( LDAP_DEBUG_ANY,
- LDAP_XSTRING(wt_dn2entry)
- ": search failed: %s (%d)\n",
+ "wt_dn2entry: search failed: %s (%d)\n",
wiredtiger_strerror(rc), rc );
goto done;
}
rc = entry_decode( &eh, &e );
if ( rc ) {
Debug( LDAP_DEBUG_ANY,
- LDAP_XSTRING(wt_dn2entry)
- ": entry decode error: %d\n",
- rc );
+ "wt_dn2entry: entry decode error: %d\n", rc );
goto done;
}
*ep = e;
done:
+
+#ifdef WT_CURSOR_CACHE
+ if(cursor){
+ cursor->reset(cursor);
+ }
+#else
if(cursor){
cursor->close(cursor);
+ wc->dn2entry = NULL;
}
+#endif
return rc;
}
return rc;
}
+/* dn2aentry - return ancestor entry */
+int wt_dn2aentry( BackendDB *be,
+ wt_ctx *wc,
+ struct berval *ndn,
+ Entry **ep ) {
+ Entry *e = NULL;
+ struct berval pdn;
+ int rc;
+
+ if (be_issuffix( be, ndn )) {
+ *ep = NULL;
+ return 0;
+ }
+
+ dnParent( ndn, &pdn );
+ rc = wt_dn2entry(be, wc, &pdn, &e);
+ switch( rc ) {
+ case 0:
+ *ep = e;
+ break;
+ case WT_NOTFOUND:
+ rc = wt_dn2aentry(be, wc, &pdn, &e);
+ if (rc != 0 && rc != WT_NOTFOUND) {
+ return rc;
+ }
+ *ep = e;
+ break;
+ default:
+ Debug( LDAP_DEBUG_ANY,
+ "wt_dn2aentry: failed %s (%d)\n",
+ wiredtiger_strerror(rc), rc );
+ }
+ return rc;
+}
+
/*
* Local variables:
* indent-tabs-mode: t
#include "slap-config.h"
#include "idl.h"
-char *
+static char *
mkrevdn(struct berval src){
char *dst, *p;
char *rdn;
rdn = src.bv_val;
src.bv_len = 0;
}
- AC_MEMCPY( p, rdn, rdn_len );
+ memcpy( p, rdn, rdn_len );
p += rdn_len;
*p++ = ',';
}
int
wt_dn2id_add(
Operation *op,
- WT_SESSION *session,
+ wt_ctx *wc,
ID pid,
Entry *e)
{
+ struct wt_info *wi = (struct wt_info *) op->o_bd->be_private;
int rc;
- WT_CURSOR *cursor = NULL;
+ WT_SESSION *session = wc->session;
+ WT_CURSOR *cursor = wc->dn2id_w;
char *revdn = NULL;
Debug( LDAP_DEBUG_TRACE, "=> wt_dn2id_add 0x%lx: \"%s\"\n",
/* make reverse dn */
revdn = mkrevdn(e->e_nname);
- rc = session->open_cursor(session, WT_TABLE_DN2ID, NULL,
- NULL, &cursor);
- if(rc){
- Debug( LDAP_DEBUG_ANY,
- LDAP_XSTRING(wt_dn2id_add)
- ": open_cursor failed: %s (%d)\n",
- wiredtiger_strerror(rc), rc );
- goto done;
- }
- cursor->set_key(cursor, e->e_ndn);
- cursor->set_value(cursor, e->e_id, pid, revdn);
+ if(!cursor){
+ rc = session->open_cursor(session, WT_TABLE_DN2ID, NULL,
+ "overwrite=false", &cursor);
+ if(rc){
+ Debug( LDAP_DEBUG_ANY,
+ "wt_dn2id_add: open_cursor failed: %s (%d)\n",
+ wiredtiger_strerror(rc), rc );
+ goto done;
+ }
+ wc->dn2id_w = cursor;
+ }
+ cursor->set_key(cursor, revdn);
+ cursor->set_value(cursor, e->e_ndn, e->e_id, pid);
rc = cursor->insert(cursor);
if(rc){
Debug( LDAP_DEBUG_ANY,
- LDAP_XSTRING(wt_dn2id_add)
- ": insert failed: %s (%d)\n",
+ "wt_dn2id_add: insert failed: %s (%d)\n",
wiredtiger_strerror(rc), rc );
goto done;
}
+ if (wi->wi_flags & WT_USE_IDLCACHE) {
+ wt_idlcache_clear(op, wc, &e->e_nname);
+ }
+
done:
if(revdn){
ch_free(revdn);
}
+
+#ifdef WT_CURSOR_CACHE
+ if(cursor){
+ cursor->reset(cursor);
+ }
+#else
if(cursor){
cursor->close(cursor);
+ wc->dn2id_w = NULL;
}
+#endif
+
Debug( LDAP_DEBUG_TRACE, "<= wt_dn2id_add 0x%lx: %d\n", e->e_id, rc );
return rc;
}
int
wt_dn2id_delete(
Operation *op,
- WT_SESSION *session,
+ wt_ctx *wc,
struct berval *ndn)
{
+ struct wt_info *wi = (struct wt_info *) op->o_bd->be_private;
int rc = 0;
- WT_CURSOR *cursor = NULL;
+ WT_SESSION *session = wc->session;
+ WT_CURSOR *cursor = wc->dn2id_w;
+ char *revdn = NULL;
Debug( LDAP_DEBUG_TRACE, "=> wt_dn2id_delete %s\n", ndn->bv_val );
- rc = session->open_cursor(session, WT_TABLE_DN2ID, NULL,
- NULL, &cursor);
- if ( rc ) {
- Debug( LDAP_DEBUG_ANY,
- LDAP_XSTRING(wt_dn2id_delete)
- ": open_cursor failed: %s (%d)\n",
- wiredtiger_strerror(rc), rc );
- goto done;
+ /* make reverse dn */
+ revdn = mkrevdn(*ndn);
+
+ if(!cursor){
+ rc = session->open_cursor(session, WT_TABLE_DN2ID, NULL,
+ "overwrite=false", &cursor);
+ if ( rc ) {
+ Debug( LDAP_DEBUG_ANY,
+ "wt_dn2id_delete: open_cursor failed: %s (%d)\n",
+ wiredtiger_strerror(rc), rc );
+ goto done;
+ }
+ wc->dn2id_w = cursor;
}
- cursor->set_key(cursor, ndn->bv_val);
+ cursor->set_key(cursor, revdn);
rc = cursor->remove(cursor);
if ( rc ) {
Debug( LDAP_DEBUG_ANY,
- LDAP_XSTRING(wt_dn2id_delete)
- ": remove failed: %s (%d)\n",
+ "wt_dn2id_delete: remove failed: %s (%d)\n",
wiredtiger_strerror(rc), rc );
goto done;
}
+ if (wi->wi_flags & WT_USE_IDLCACHE) {
+ wt_idlcache_clear(op, wc, ndn);
+ }
+
Debug( LDAP_DEBUG_TRACE,
- "<= wt_dn2id_delete %s: %d\n",
- ndn->bv_val, rc );
+ "<= wt_dn2id_delete %s: %d\n", ndn->bv_val, rc );
done:
+ if(revdn){
+ ch_free(revdn);
+ }
+
+#ifdef WT_CURSOR_CACHE
+ if(cursor){
+ cursor->reset(cursor);
+ }
+#else
if(cursor){
cursor->close(cursor);
+ wc->dn2id_w = NULL;
}
+#endif
return rc;
}
int
wt_dn2id(
Operation *op,
- WT_SESSION *session,
+ wt_ctx *wc,
struct berval *ndn,
ID *id)
{
- WT_CURSOR *cursor = NULL;
- struct wt_info *wi = (struct wt_info *) op->o_bd->be_private;
- int rc;
- ID nid;
+ WT_SESSION *session = wc->session;
+ WT_CURSOR *cursor = wc->dn2id_ndn;
+ int rc = LDAP_SUCCESS;
- Debug( LDAP_DEBUG_TRACE, "=> wt_dn2id(\"%s\")\n",
- ndn->bv_val );
+ Debug( LDAP_DEBUG_TRACE, "=> wt_dn2id(\"%s\")\n", ndn->bv_val );
if ( ndn->bv_len == 0 ) {
*id = 0;
goto done;
}
- rc = session->open_cursor(session, WT_TABLE_DN2ID
- "(id)",
- NULL, NULL, &cursor);
- if( rc ){
- Debug( LDAP_DEBUG_ANY,
- LDAP_XSTRING(wt_dn2id)
- ": cursor open failed: %s (%d)\n",
- wiredtiger_strerror(rc), rc );
- goto done;
+ if(!cursor){
+ rc = session->open_cursor(session, WT_INDEX_NDN
+ "(id)",
+ NULL, NULL, &cursor);
+ if( rc ){
+ Debug( LDAP_DEBUG_ANY,
+ "wt_dn2id: cursor open failed: %s (%d)\n",
+ wiredtiger_strerror(rc), rc );
+ goto done;
+ }
+ wc->dn2id_ndn = cursor;
}
cursor->set_key(cursor, ndn->bv_val);
goto done;
default:
Debug( LDAP_DEBUG_ANY,
- LDAP_XSTRING(wt_dn2id)
- ": search failed: %s (%d)\n",
+ "wt_dn2id: search failed: %s (%d)\n",
wiredtiger_strerror(rc), rc );
goto done;
}
rc = cursor->get_value(cursor, id);
if( rc ){
Debug( LDAP_DEBUG_ANY,
- LDAP_XSTRING(wt_dn2id)
- ": get_value failed: %s (%d)\n",
+ "wt_dn2id: get_value failed: %s (%d)\n",
wiredtiger_strerror(rc), rc );
goto done;
}
done:
+
+#ifdef WT_CURSOR_CACHE
+ if(cursor){
+ cursor->reset(cursor);
+ }
+#else
if(cursor){
cursor->close(cursor);
+ wc->dn2id_ndn = NULL;
}
+#endif
if( rc ) {
Debug( LDAP_DEBUG_TRACE, "<= wt_dn2id: get failed: %s (%d)\n",
int
wt_dn2id_has_children(
Operation *op,
- WT_SESSION *session,
+ wt_ctx *wc,
ID id )
{
- struct wt_info *wi = (struct wt_info *) op->o_bd->be_private;
- WT_CURSOR *cursor = NULL;
+ WT_SESSION *session = wc->session;
+ WT_CURSOR *cursor = wc->index_pid;
int rc;
uint64_t key = id;
- rc = session->open_cursor(session, WT_INDEX_PID,
- NULL, NULL, &cursor);
- if( rc ){
- Debug( LDAP_DEBUG_ANY,
- LDAP_XSTRING(wt_dn2id_has_children)
- ": cursor open failed: %s (%d)\n",
- wiredtiger_strerror(rc), rc );
- goto done;
+ if(!cursor){
+ rc = session->open_cursor(session, WT_INDEX_PID,
+ NULL, NULL, &cursor);
+ if( rc ){
+ Debug( LDAP_DEBUG_ANY,
+ "wt_dn2id_has_children: cursor open failed: %s (%d)\n",
+ wiredtiger_strerror(rc), rc );
+ goto done;
+ }
+ wc->index_pid = cursor;
}
cursor->set_key(cursor, key);
rc = cursor->search(cursor);
done:
+
+#ifdef WT_CURSOR_CACHE
+ if(cursor){
+ cursor->reset(cursor);
+ }
+#else
if(cursor){
cursor->close(cursor);
+ wc->index_pid = NULL;
}
+#endif
return rc;
}
int
-wt_dn2idl(
+wt_dn2idl_db(
Operation *op,
- WT_SESSION *session,
+ wt_ctx *wc,
struct berval *ndn,
Entry *e,
ID *ids,
ID *stack)
{
- struct wt_info *wi = (struct wt_info *) op->o_bd->be_private;
- WT_CURSOR *cursor = NULL;
- int exact = 0;
+ WT_SESSION *session = wc->session;
+ WT_CURSOR *cursor = wc->dn2id;
int rc;
char *revdn = NULL;
size_t revdn_len;
"=> wt_dn2idl(\"%s\")\n",
ndn->bv_val );
- if(op->ors_scope != LDAP_SCOPE_ONELEVEL &&
- be_issuffix( op->o_bd, &e->e_nname )){
- WT_IDL_ALL(wi, ids);
- return 0;
- }
-
revdn = mkrevdn(*ndn);
revdn_len = strlen(revdn);
- rc = session->open_cursor(session, WT_INDEX_REVDN"(id, pid)",
- NULL, NULL, &cursor);
- if( rc ){
- Debug( LDAP_DEBUG_ANY,
- LDAP_XSTRING(wt_dn2idl)
- ": cursor open failed: %s (%d)\n",
- wiredtiger_strerror(rc), rc );
- goto done;
+
+ if ( !cursor ) {
+ rc = session->open_cursor(session, WT_TABLE_DN2ID"(id, pid)",
+ NULL, NULL, &cursor);
+ if( rc ){
+ Debug( LDAP_DEBUG_ANY,
+ "wt_dn2idl: cursor open failed: %s (%d)\n",
+ wiredtiger_strerror(rc), rc );
+ goto done;
+ }
+ wc->dn2id = cursor;
}
cursor->set_key(cursor, revdn);
- rc = cursor->search_near(cursor, &exact);
+ rc = cursor->search(cursor);
if( rc ){
Debug( LDAP_DEBUG_ANY,
- LDAP_XSTRING(wt_dn2idl)
- ": search failed: %s (%d)\n",
+ "wt_dn2idl: search failed: %s (%d)\n",
wiredtiger_strerror(rc), rc );
goto done;
}
+ if( op->ors_scope == LDAP_SCOPE_CHILDREN ) {
+ cursor->next(cursor);
+ }
+
do {
rc = cursor->get_key(cursor, &key);
if( rc ){
Debug( LDAP_DEBUG_ANY,
- LDAP_XSTRING(wt_dn2idl)
- ": get_key failed: %s (%d)\n",
+ "wt_dn2idl: get_key failed: %s (%d)\n",
wiredtiger_strerror(rc), rc );
goto done;
}
-
- if( strncmp(revdn, key, revdn_len) ){
- if(exact < 0){
- rc = cursor->next(cursor);
- if (rc) {
- break;
- }else{
- continue;
- }
- }
- break;
- }
- exact = 0;
rc = cursor->get_value(cursor, &id, &pid);
if( rc ){
Debug( LDAP_DEBUG_ANY,
- LDAP_XSTRING(wt_dn2id)
- ": get_value failed: %s (%d)\n",
+ "wt_dn2id: get_value failed: %s (%d)\n",
wiredtiger_strerror(rc), rc );
goto done;
}
- if( op->ors_scope == LDAP_SCOPE_ONELEVEL &&
- e->e_id != pid){
- rc = cursor->next(cursor);
- if ( rc ) {
- break;
- }
- continue;
- }else{
- wt_idl_append_one(ids, id);
+
+ if( strncmp(revdn, key, revdn_len) ){
+ break;
+ }
+
+ if( op->ors_scope == LDAP_SCOPE_ONELEVEL && e->e_id != pid ){
+ goto next;
}
+ wt_idl_append_one(ids, id);
+ next:
rc = cursor->next(cursor);
}while(rc == 0);
rc = LDAP_SUCCESS;
}
+ wt_idl_sort(ids, stack);
+ Debug( LDAP_DEBUG_TRACE,
+ "<= wt_dn2idl_db: size=%ld first=%ld last=%ld\n",
+ (long) ids[0],
+ (long) WT_IDL_FIRST(ids),
+ (long) WT_IDL_LAST(ids) );
+
done:
if(revdn){
ch_free(revdn);
}
+#ifdef WT_CURSOR_CACHE
+ if(cursor){
+ cursor->reset(cursor);
+ }
+#else
if(cursor){
cursor->close(cursor);
+ wc->dn2id = NULL;
}
+#endif
return rc;
}
-#if 0
int
-wt_dn2id(
+wt_dn2idl(
Operation *op,
- WT_SESSION *session,
- struct berval *dn,
- ID *id)
+ wt_ctx *wc,
+ struct berval *ndn,
+ Entry *e,
+ ID *ids,
+ ID *stack)
{
- struct wt_info *wi = (struct wy_info *) op->o_bd->be_private;
- WT_CURSOR *cursor = NULL;
+ struct wt_info *wi = (struct wt_info *) op->o_bd->be_private;
int rc;
- Debug( LDAP_DEBUG_TRACE, "=> wt_dn2id(\"%s\")\n", dn->bv_val );
- rc = session->open_cursor(session, WT_INDEX_DN"(id)",
- NULL, NULL, &cursor);
- if( rc ){
- Debug( LDAP_DEBUG_ANY,
- LDAP_XSTRING(wt_dn2id)
- ": cursor open failed: %s (%d)\n",
- wiredtiger_strerror(rc), rc );
- return rc;
+ Debug( LDAP_DEBUG_TRACE,
+ "=> wt_dn2idl(\"%s\")\n", ndn->bv_val );
+
+ if(op->ors_scope != LDAP_SCOPE_ONELEVEL &&
+ be_issuffix( op->o_bd, &e->e_nname )){
+ WT_IDL_ALL(wi, ids);
+ return 0;
}
- cursor->set_key(cursor, dn->bv_val);
- rc = cursor->search(cursor);
- if( !rc ){
- cursor->get_key(cursor, &id);
+
+ if (wi->wi_flags & WT_USE_IDLCACHE) {
+ rc = wt_idlcache_get(wc, ndn, op->ors_scope, ids);
+ if (rc == 0) {
+ /* cache hit */
+ return rc;
+ }
+ /* cache miss */
+ }
+
+ if ( wi->wi_flags & WT_USE_IDLCACHE ) {
+ wt_idlcache_begin(wc, ndn, op->ors_scope);
+ }
+ rc = wt_dn2idl_db(op, wc, ndn, e, ids, stack);
+ if ( rc == 0 && wi->wi_flags & WT_USE_IDLCACHE ) {
+ wt_idlcache_set(wc, ndn, op->ors_scope, ids);
}
- cursor->close(cursor);
+
return rc;
}
-#endif
/*
* Local variables:
--- /dev/null
+/* OpenLDAP WiredTiger backend */
+/* $OpenLDAP$ */
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
+ *
+ * Copyright 2002-2015 The OpenLDAP Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted only as authorized by the OpenLDAP
+ * Public License.
+ *
+ * A copy of this license is available in the file LICENSE in the
+ * top-level directory of the distribution or, alternatively, at
+ * <http://www.OpenLDAP.org/license.html>.
+ */
+/* ACKNOWLEDGEMENTS:
+ * This work was developed by HAMANO Tsukasa <hamano@osstech.co.jp>
+ * based on back-bdb for inclusion in OpenLDAP Software.
+ * WiredTiger is a product of MongoDB Inc.
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+#include <ac/string.h>
+
+#include "back-wt.h"
+#include "lber_pvt.h"
+
+static struct exop {
+ struct berval *oid;
+ BI_op_extended *extended;
+} exop_table[] = {
+ { NULL, NULL }
+};
+
+int
+wt_extended( Operation *op, SlapReply *rs )
+{
+ int i;
+
+ for( i=0; exop_table[i].extended != NULL; i++ ) {
+ if( ber_bvcmp( exop_table[i].oid, &op->oq_extended.rs_reqoid ) == 0 ) {
+ return (exop_table[i].extended)( op, rs );
+ }
+ }
+
+ rs->sr_text = "not supported within naming context";
+ return rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
+}
+
+/*
+ * Local variables:
+ * indent-tabs-mode: t
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ */
}
/* open index cursor */
- cursor = wt_ctx_index_cursor(wc, &desc->ad_type->sat_cname, 0);
+ cursor = wt_index_open(wc, &desc->ad_type->sat_cname, 0);
if( !cursor ) {
Debug( LDAP_DEBUG_ANY,
"<= wt_presence_candidates: open index cursor failed: %s\n",
rc = wt_key_read( op->o_bd, cursor, &prefix, ids, NULL, 0 );
- if(cursor){
- cursor->close(cursor);
- }
+ cursor->close(cursor);
Debug(LDAP_DEBUG_TRACE,
"<= wt_presence_candidates: id=%ld first=%ld last=%ld\n",
(long) ids[0],
MatchingRule *mr;
WT_CURSOR *cursor = NULL;
- Debug( LDAP_DEBUG_TRACE, "=> wt_equality_candidates (%s)\n",
- ava->aa_desc->ad_cname.bv_val );
+ Debug( LDAP_DEBUG_TRACE, "=> wt_equality_candidates (%s=%s)\n",
+ ava->aa_desc->ad_cname.bv_val, ava->aa_value.bv_val );
if ( ava->aa_desc == slap_schema.si_ad_entryDN ) {
ID id = NOID;
- rc = wt_dn2id(op, wc->session, &ava->aa_value, &id);
+ rc = wt_dn2id(op, wc, &ava->aa_value, &id);
if( rc == 0 ){
wt_idl_append_one(ids, id);
}else if ( rc == WT_NOTFOUND ) {
}
/* open index cursor */
- cursor = wt_ctx_index_cursor(wc, &ava->aa_desc->ad_type->sat_cname, 0);
+ cursor = wt_index_open(wc, &ava->aa_desc->ad_type->sat_cname, 0);
if( !cursor ) {
Debug( LDAP_DEBUG_ANY,
"<= wt_equality_candidates: open index cursor failed: %s\n",
break;
} else if( rc != LDAP_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE,
- "<= wt_equality_candidates: (%s) "
- "key read failed (%d)\n",
+ "<= wt_equality_candidates: (%s) key read failed (%d)\n",
ava->aa_desc->ad_cname.bv_val, rc );
break;
}
ber_bvarray_free_x( keys, op->o_tmpmemctx );
- if(cursor){
- cursor->close(cursor);
- }
+ cursor->close(cursor);
Debug( LDAP_DEBUG_TRACE,
"<= wt_equality_candidates: id=%ld, first=%ld, last=%ld\n",
}
/* open index cursor */
- cursor = wt_ctx_index_cursor(wc, &ava->aa_desc->ad_type->sat_cname, 0);
+ cursor = wt_index_open(wc, &ava->aa_desc->ad_type->sat_cname, 0);
if( !cursor ) {
Debug( LDAP_DEBUG_ANY,
"<= wt_approx_candidates: open index cursor failed: %s\n",
ber_bvarray_free_x( keys, op->o_tmpmemctx );
- if(cursor){
- cursor->close(cursor);
- }
+ cursor->close(cursor);
Debug( LDAP_DEBUG_TRACE,
"<= wt_approx_candidates %ld, first=%ld, last=%ld\n",
if( rc != LDAP_SUCCESS ) {
Debug( LDAP_DEBUG_ANY,
- "<= wt_substring_candidates: (%s) "
- "index_param failed (%d)\n",
+ "<= wt_substring_candidates: (%s) index_param failed (%d)\n",
sub->sa_desc->ad_cname.bv_val, rc );
return 0;
}
}
/* open index cursor */
- cursor = wt_ctx_index_cursor(wc, &sub->sa_desc->ad_cname, 0);
+ cursor = wt_index_open(wc, &sub->sa_desc->ad_cname, 0);
if( !cursor ) {
Debug( LDAP_DEBUG_ANY,
"<= wt_substring_candidates: open index cursor failed: %s\n",
ber_bvarray_free_x( keys, op->o_tmpmemctx );
- if(cursor){
- cursor->close(cursor);
- }
+ cursor->close(cursor);
Debug( LDAP_DEBUG_TRACE,
"<= wt_substring_candidates: %ld, first=%ld, last=%ld\n",
return rc;
}
+#ifdef LDAP_COMP_MATCH
+static int
+comp_candidates (
+ Operation *op,
+ wt_ctx *wc,
+ MatchingRuleAssertion *mra,
+ ComponentFilter *f,
+ ID *ids,
+ ID *tmp,
+ ID *stack)
+{
+ int rc = 0;
+
+ if ( !f ) return LDAP_PROTOCOL_ERROR;
+
+ Debug( LDAP_DEBUG_FILTER, "comp_candidates\n" );
+ /* TODO: */
+ Debug( LDAP_DEBUG_FILTER, "=> not implement yet\n" );
+ return( rc );
+}
+
+#endif
+
+static int
+ext_candidates(
+ Operation *op,
+ wt_ctx *wc,
+ MatchingRuleAssertion *mra,
+ ID *ids,
+ ID *tmp,
+ ID *stack )
+{
+ struct wt_info *wi = (struct wt_info *) op->o_bd->be_private;
+
+#ifdef LDAP_COMP_MATCH
+ /*
+ * Currently Only Component Indexing for componentFilterMatch is supported
+ * Indexing for an extensible filter is not supported yet
+ */
+ if ( mra->ma_cf ) {
+ return comp_candidates ( op, wc, mra, mra->ma_cf, ids, tmp, stack);
+ }
+#endif
+ if ( mra->ma_desc == slap_schema.si_ad_entryDN ) {
+ /* TODO: */
+ Debug( LDAP_DEBUG_FILTER, "=> not implement yet.\n" );
+ }
+ WT_IDL_ALL( wi, ids );
+ return 0;
+}
static int
list_candidates(
ID *stack )
{
struct wt_info *wi = (struct wt_info *)op->o_bd->be_private;
- int rc = 0;
+ int rc = LDAP_SUCCESS;
Debug( LDAP_DEBUG_FILTER, "=> wt_filter_candidates\n" );
if ( f->f_choice & SLAPD_FILTER_UNDEFINED ) {
break;
case LDAP_FILTER_EXT:
- /* TODO: not implement yet */
Debug( LDAP_DEBUG_FILTER, "\tEXT\n" );
- rc = presence_candidates( op, wc, f->f_ava->aa_desc, ids );
+ rc = ext_candidates( op, wc, f->f_mra, ids, tmp, stack);
break;
default:
(long) ids[0],
(long) WT_IDL_FIRST( ids ),
(long) WT_IDL_LAST( ids ) );
- return 0;
+ return rc;
}
/*
static int wt_id2entry_put(
Operation *op,
- WT_SESSION *session,
+ wt_ctx *wc,
Entry *e,
- const char *config )
+ WT_CURSOR *cursor)
{
struct berval bv;
- WT_CURSOR *cursor = NULL;
WT_ITEM item;
int rc;
item.size = bv.bv_len;
item.data = bv.bv_val;
- rc = session->open_cursor(session, WT_TABLE_ID2ENTRY, NULL,
- config, &cursor);
- if ( rc ) {
- Debug( LDAP_DEBUG_ANY,
- LDAP_XSTRING(wt_id2entry_put)
- ": open_cursor failed: %s (%d)\n",
- wiredtiger_strerror(rc), rc );
- goto done;
- }
cursor->set_key(cursor, e->e_id);
cursor->set_value(cursor, e->e_ndn, &item);
rc = cursor->insert(cursor);
if ( rc ) {
Debug( LDAP_DEBUG_ANY,
- LDAP_XSTRING(wt_id2entry_put)
- ": insert failed: %s (%d)\n",
+ "wt_id2entry_put: insert failed: %s (%d)\n",
wiredtiger_strerror(rc), rc );
goto done;
}
done:
ch_free( bv.bv_val );
- if(cursor){
- cursor->close(cursor);
- }
+
return rc;
}
int wt_id2entry_add(
Operation *op,
- WT_SESSION *session,
+ wt_ctx *wc,
Entry *e )
{
- return wt_id2entry_put(op, session, e, "overwrite=false");
+ WT_SESSION *session = wc->session;
+ WT_CURSOR *cursor = wc->id2entry_add;
+ int rc;
+
+ if(!cursor){
+ rc = session->open_cursor(session, WT_TABLE_ID2ENTRY, NULL,
+ "overwrite=false", &cursor);
+ if ( rc ) {
+ Debug( LDAP_DEBUG_ANY,
+ "wt_id2entry_put: open_cursor failed: %s (%d)\n",
+ wiredtiger_strerror(rc), rc );
+ return rc;
+ }
+ wc->id2entry_add = cursor;
+ }
+
+ rc = wt_id2entry_put(op, wc, e, cursor);
+
+#ifdef WT_CURSOR_CACHE
+ if(cursor){
+ cursor->reset(cursor);
+ }
+#else
+ if(cursor){
+ cursor->close(cursor);
+ wc->id2entry_add = NULL;
+ }
+#endif
+
+ return rc;
}
int wt_id2entry_update(
Operation *op,
- WT_SESSION *session,
+ wt_ctx *wc,
Entry *e )
{
- return wt_id2entry_put(op, session, e, "overwrite=true");
+ WT_SESSION *session = wc->session;
+ WT_CURSOR *cursor = wc->id2entry_update;
+ int rc;
+
+ if(!cursor){
+ rc = session->open_cursor(session, WT_TABLE_ID2ENTRY, NULL,
+ "overwrite=true", &cursor);
+ if ( rc ) {
+ Debug( LDAP_DEBUG_ANY,
+ "wt_id2entry_put: open_cursor failed: %s (%d)\n",
+ wiredtiger_strerror(rc), rc );
+ return rc;
+ }
+ wc->id2entry_update = cursor;
+ }
+ rc = wt_id2entry_put(op, wc, e, cursor);
+
+#ifdef WT_CURSOR_CACHE
+ if(cursor){
+ cursor->reset(cursor);
+ }
+#else
+ if(cursor){
+ cursor->close(cursor);
+ wc->id2entry_update = NULL;
+ }
+#endif
+ return rc;
}
int wt_id2entry_delete(
Operation *op,
- WT_SESSION *session,
+ wt_ctx *wc,
Entry *e )
{
int rc;
+ WT_SESSION *session = wc->session;
WT_CURSOR *cursor = NULL;
+
rc = session->open_cursor(session, WT_TABLE_ID2ENTRY, NULL,
NULL, &cursor);
if ( rc ) {
Debug( LDAP_DEBUG_ANY,
- LDAP_XSTRING(wt_id2entry_delete)
- ": open_cursor failed: %s (%d)\n",
+ "wt_id2entry_delete: open_cursor failed: %s (%d)\n",
wiredtiger_strerror(rc), rc );
goto done;
}
rc = cursor->remove(cursor);
if ( rc ) {
Debug( LDAP_DEBUG_ANY,
- LDAP_XSTRING(wt_id2entry_delete)
- ": remove failed: %s (%d)\n",
+ "wt_id2entry_delete: remove failed: %s (%d)\n",
wiredtiger_strerror(rc), rc );
goto done;
}
}
int wt_id2entry( BackendDB *be,
- WT_SESSION *session,
+ wt_ctx *wc,
ID id,
Entry **ep ){
int rc;
- WT_CURSOR *cursor = NULL;
+ WT_SESSION *session = wc->session;
+ WT_CURSOR *cursor = wc->id2entry;
WT_ITEM item;
EntryHeader eh;
int eoff;
Entry *e = NULL;
- rc = session->open_cursor(session, WT_TABLE_ID2ENTRY"(entry)", NULL,
- NULL, &cursor);
- if ( rc ) {
- Debug( LDAP_DEBUG_ANY,
- LDAP_XSTRING(wt_id2entry)
- ": open_cursor failed: %s (%d)\n",
- wiredtiger_strerror(rc), rc );
- goto done;
+ if(!cursor){
+ rc = session->open_cursor(session, WT_TABLE_ID2ENTRY"(entry)", NULL,
+ NULL, &cursor);
+ if ( rc ) {
+ Debug( LDAP_DEBUG_ANY,
+ "wt_id2entry: open_cursor failed: %s (%d)\n",
+ wiredtiger_strerror(rc), rc );
+ goto done;
+ }
+ wc->id2entry = cursor;
}
cursor->set_key(cursor, id);
rc = entry_decode( &eh, &e );
if ( rc ) {
Debug( LDAP_DEBUG_ANY,
- LDAP_XSTRING(wt_id2entry)
- ": entry decode error: %d\n",
- rc );
+ "wt_id2entry: entry decode error: %s (%d)\n",
+ wiredtiger_strerror(rc), rc );
goto done;
}
e->e_id = id;
*ep = e;
done:
+
+#ifdef WT_CURSOR_CACHE
+ if(cursor){
+ cursor->reset(cursor);
+ }
+#else
if(cursor){
cursor->close(cursor);
+ wc->id2entry = NULL;
}
+#endif
return rc;
}
Entry *e,
int rw )
{
- struct wt_info *wi = (struct wt_info *) op->o_bd->be_private;
return wt_entry_return( e );
}
int rw,
Entry **ent )
{
- return 0;
+ struct wt_info *wi = (struct wt_info *) op->o_bd->be_private;
+ wt_ctx *wc;
+ Entry *e = NULL;
+ int rc;
+ const char *at_name = at ? at->ad_cname.bv_val : "(null)";
+
+ Debug( LDAP_DEBUG_ARGS,
+ "wt_entry_get: ndn: \"%s\"\n", ndn->bv_val );
+ Debug( LDAP_DEBUG_ARGS,
+ "wt_entry_get: oc: \"%s\", at: \"%s\"\n",
+ oc ? oc->soc_cname.bv_val : "(null)", at_name );
+
+ wc = wt_ctx_get(op, wi);
+ if( !wc ){
+ Debug( LDAP_DEBUG_ANY,
+ "wt_entry_get: wt_ctx_get failed\n" );
+ return LDAP_OTHER;
+ }
+ rc = wt_dn2entry(op->o_bd, wc, ndn, &e);
+ switch( rc ) {
+ case 0:
+ break;
+ case WT_NOTFOUND:
+ Debug( LDAP_DEBUG_ACL,
+ "wt_entry_get: cannot find entry: \"%s\"\n",
+ ndn->bv_val );
+ return LDAP_NO_SUCH_OBJECT;
+ default:
+ Debug( LDAP_DEBUG_ANY,
+ "wt_entry_get: wt_dn2entry failed %s rc=%d\n",
+ wiredtiger_strerror(rc), rc );
+ rc = LDAP_OTHER;
+ }
+
+ Debug( LDAP_DEBUG_ACL,
+ "wt_entry_get: found entry: \"%s\"\n", ndn->bv_val );
+
+ if ( oc && !is_entry_objectclass( e, oc, 0 )) {
+ Debug( LDAP_DEBUG_ACL,
+ "wt_entry_get: failed to find objectClass %s\n",
+ oc->soc_cname.bv_val );
+ rc = LDAP_NO_SUCH_ATTRIBUTE;
+ goto return_results;
+ }
+
+ /* NOTE: attr_find() or attrs_find()? */
+ if ( at && attr_find( e->e_attrs, at ) == NULL ) {
+ Debug( LDAP_DEBUG_ACL,
+ "wt_entry_get: failed to find attribute %s\n",
+ at->ad_cname.bv_val );
+ rc = LDAP_NO_SUCH_ATTRIBUTE;
+ goto return_results;
+ }
+
+return_results:
+ if( rc != LDAP_SUCCESS ) {
+ wt_entry_return( e );
+ }else{
+ *ent = e;
+ }
+
+ Debug( LDAP_DEBUG_TRACE, "wt_entry_get: rc=%d\n", rc );
+
+ return rc;
}
/*
#define IDL_MIN(x,y) ( (x) < (y) ? (x) : (y) )
#define IDL_CMP(x,y) ( (x) < (y) ? -1 : (x) > (y) )
-#if IDL_DEBUG > 0
-static void idl_check( ID *ids )
+void wt_idl_check( ID *ids )
{
if( WT_IDL_IS_RANGE( ids ) ) {
assert( WT_IDL_RANGE_FIRST(ids) <= WT_IDL_RANGE_LAST(ids) );
}
}
-#if IDL_DEBUG > 1
-static void idl_dump( ID *ids )
+void wt_idl_dump( ID *ids )
{
if( WT_IDL_IS_RANGE( ids ) ) {
Debug( LDAP_DEBUG_ANY,
Debug( LDAP_DEBUG_ANY, "\n" );
}
- idl_check( ids );
+ wt_idl_check( ids );
}
-#endif /* IDL_DEBUG > 1 */
-#endif /* IDL_DEBUG > 0 */
unsigned wt_idl_search( ID *ids, ID id )
{
Debug( LDAP_DEBUG_ANY, "insert: %04lx at %d\n", (long) id, x );
idl_dump( ids );
#elif IDL_DEBUG > 0
- idl_check( ids );
+ wt_idl_check( ids );
#endif
if (WT_IDL_IS_RANGE( ids )) {
}
#if IDL_DEBUG > 1
- idl_dump( ids );
+ wt_idl_dump( ids );
#elif IDL_DEBUG > 0
- idl_check( ids );
+ wt_idl_check( ids );
#endif
return 0;
Debug( LDAP_DEBUG_ANY, "delete: %04lx at %d\n", (long) id, x );
idl_dump( ids );
#elif IDL_DEBUG > 0
- idl_check( ids );
+ wt_idl_check( ids );
#endif
if (WT_IDL_IS_RANGE( ids )) {
}
#if IDL_DEBUG > 1
- idl_dump( ids );
+ wt_idl_dump( ids );
#elif IDL_DEBUG > 0
- idl_check( ids );
+ wt_idl_check( ids );
#endif
return 0;
* WiredTiger is a product of MongoDB Inc.
*/
-#ifndef _WI_IDL_H_
+#ifndef _WT_IDL_H_
#define _WT_IDL_H_
/* IDL sizes - likely should be even bigger
#include "portable.h"
#include <stdio.h>
+#include <ac/string.h>
#include "back-wt.h"
#include "slap-config.h"
struct berval *prefixp )
{
AttrInfo *ai;
- int rc;
slap_mask_t mask, type = 0;
ai = wt_index_mask( be, desc, prefixp );
int opid,
slap_mask_t mask )
{
- int rc, i;
+ int rc = LDAP_SUCCESS, i;
struct berval *keys;
WT_CURSOR *cursor = NULL;
- WT_SESSION *session = wc->session;
assert( mask != 0 );
- cursor = wt_ctx_index_cursor(wc, atname, 1);
+ cursor = wt_index_open(wc, atname, 1);
if( !cursor ) {
Debug( LDAP_DEBUG_ANY,
- LDAP_XSTRING(indexer)
- ": open index cursor failed: %s\n",
+ "indexer: open index cursor failed: %s\n",
atname->bv_val );
goto done;
}
}
done:
- if(cursor){
- cursor->close(cursor);
- }
+ cursor->close(cursor);
return rc;
}
ID id,
int opid )
{
- int rc;
+ int rc = LDAP_SUCCESS;
slap_mask_t mask = 0;
int ixop = opid;
AttrInfo *ai = NULL;
return 0;
}
+WT_CURSOR *
+wt_index_open(wt_ctx *wc, struct berval *name, int create)
+{
+ WT_CURSOR *cursor = NULL;
+ WT_SESSION *session = wc->session;
+ char uri[1024];
+ int rc;
+
+ snprintf(uri, sizeof(uri), "table:%s", name->bv_val);
+
+ rc = session->open_cursor(session, uri, NULL, "overwrite=false", &cursor);
+ if (rc == ENOENT && create) {
+ rc = session->create(session, uri,
+ "key_format=uQ,"
+ "value_format=x,"
+ "columns=(key, id, none)");
+ if( rc ) {
+ Debug( LDAP_DEBUG_ANY,
+ "wt_index_open: table \"%s\": "
+ "cannot create index table: %s (%d)\n",
+ uri, wiredtiger_strerror(rc), rc);
+ return NULL;
+ }
+ rc = session->open_cursor(session, uri, NULL,
+ "overwrite=false", &cursor);
+ }
+ if ( rc ) {
+ Debug( LDAP_DEBUG_ANY,
+ "wt_index_open: table \"%s\": "
+ ": open cursor failed: %s (%d)\n",
+ uri, wiredtiger_strerror(rc), rc);
+ return NULL;
+ }
+ return cursor;
+}
+
/*
* Local variables:
* indent-tabs-mode: t
{
struct wt_info *wi;
- Debug( LDAP_DEBUG_TRACE,
- LDAP_XSTRING(wt_db_init) ": Initializing wt backend\n" );
+ Debug( LDAP_DEBUG_TRACE, "wt_db_init: Initializing wt backend\n" );
/* allocate backend-database-specific stuff */
- wi = ch_calloc( 1, sizeof(struct wt_info) );
-
- wi->wi_dbenv_home = ch_strdup( SLAPD_DEFAULT_DB_DIR );
- wi->wi_dbenv_config = ch_strdup("create");
+ wi = ch_calloc( 1, sizeof(struct wt_info) );
+ wi->wi_home = ch_strdup( SLAPD_DEFAULT_DB_DIR );
+ wi->wi_config = ch_calloc( 1, WT_CONFIG_MAX + 1);
+ if ( slapMode & SLAP_TOOL_READONLY ) {
+ strcpy(wi->wi_config, "readonly");
+ } else {
+ strcpy(wi->wi_config, "create");
+ }
wi->wi_lastid = 0;
wi->wi_search_stack_depth = DEFAULT_SEARCH_STACK_DEPTH;
wi->wi_search_stack = NULL;
+ wi->wi_flags = WT_USE_IDLCACHE;
be->be_private = wi;
be->be_cf_ocs = be->bd_info->bi_cf_ocs;
struct wt_info *wi = (struct wt_info *) be->be_private;
int rc;
struct stat st;
- WT_CONNECTION *conn;
- WT_SESSION *session;
+ WT_SESSION *session = NULL;
+ WT_SESSION *cache_session = NULL;
if ( be->be_suffix == NULL ) {
- Debug( LDAP_DEBUG_ANY,
- LDAP_XSTRING(wt_db_open) ": need suffix.\n" );
+ Debug( LDAP_DEBUG_ANY, "wt_db_open: need suffix.\n" );
return -1;
}
Debug( LDAP_DEBUG_ARGS,
- LDAP_XSTRING(wt_db_open) ": \"%s\"\n",
- be->be_suffix[0].bv_val );
+ "wt_db_open: \"%s\", home=%s, config=%s\n",
+ be->be_suffix[0].bv_val, wi->wi_home, wi->wi_config );
/* Check existence of home. Any error means trouble */
- rc = stat( wi->wi_dbenv_home, &st );
+ rc = stat( wi->wi_home, &st );
if( rc ) {
int saved_errno = errno;
Debug( LDAP_DEBUG_ANY,
- LDAP_XSTRING(wt_db_open) ": database \"%s\": "
+ "wt_db_open: database \"%s\": "
"cannot access database directory \"%s\" (%d).\n",
- be->be_suffix[0].bv_val, wi->wi_dbenv_home, saved_errno );
+ be->be_suffix[0].bv_val, wi->wi_home, saved_errno );
return -1;
}
/* Open and create database */
- rc = wiredtiger_open(wi->wi_dbenv_home, NULL,
- wi->wi_dbenv_config, &conn);
+ rc = wiredtiger_open(wi->wi_home, NULL,
+ wi->wi_config, &wi->wi_conn);
if( rc ) {
int saved_errno = errno;
Debug( LDAP_DEBUG_ANY,
- LDAP_XSTRING(wt_db_open) ": database \"%s\": "
+ "wt_db_open: database \"%s\": "
"cannot open database \"%s\" (%d).\n",
- be->be_suffix[0].bv_val, wi->wi_dbenv_home, saved_errno );
+ be->be_suffix[0].bv_val, wi->wi_home, saved_errno );
return -1;
}
- rc = conn->open_session(conn, NULL, NULL, &session);
+ rc = wi->wi_conn->open_session(wi->wi_conn, NULL, NULL, &session);
if( rc ) {
Debug( LDAP_DEBUG_ANY,
- LDAP_XSTRING(wt_db_open) ": database \"%s\": "
+ "wt_db_open: database \"%s\": "
"cannot open session: \"%s\"\n",
be->be_suffix[0].bv_val, wiredtiger_strerror(rc) );
return -1;
}
+ if ( slapMode & SLAP_TOOL_READONLY ) {
+ goto readonly;
+ }
+
+ /* checking for obsolete table */
+ rc = session->verify(session, WT_INDEX_REVDN, NULL);
+ if ( !rc ) {
+ Debug( LDAP_DEBUG_ANY,
+ "wt_db_open: database \"%s\": "
+ "incompatible wiredtiger table, please restore from LDIF.\n",
+ be->be_suffix[0].bv_val );
+ return -1;
+ }
+
+ /* create tables and indexes */
rc = session->create(session,
WT_TABLE_ID2ENTRY,
"key_format=Q,"
"columns=(id,dn,entry)");
if( rc ) {
Debug( LDAP_DEBUG_ANY,
- LDAP_XSTRING(wt_db_open) ": database \"%s\": "
+ "wt_db_open: database \"%s\": "
"cannot create entry table: \"%s\"\n",
be->be_suffix[0].bv_val, wiredtiger_strerror(rc) );
return -1;
rc = session->create(session,
WT_TABLE_DN2ID,
"key_format=S,"
- "value_format=QQS,"
- "columns=(ndn,id,pid,revdn)");
+ "value_format=SQQ,"
+ "columns=(revdn,ndn,id,pid)");
if( rc ) {
Debug( LDAP_DEBUG_ANY,
- LDAP_XSTRING(wt_db_open) ": database \"%s\": "
+ "wt_db_open: database \"%s\": "
"cannot create entry table: \"%s\"\n",
be->be_suffix[0].bv_val, wiredtiger_strerror(rc) );
return -1;
rc = session->create(session, WT_INDEX_DN, "columns=(dn)");
if( rc ) {
Debug( LDAP_DEBUG_ANY,
- LDAP_XSTRING(wt_db_open) ": database \"%s\": "
+ "wt_db_open: database \"%s\": "
"cannot create dn index: \"%s\"\n",
be->be_suffix[0].bv_val, wiredtiger_strerror(rc) );
return -1;
rc = session->create(session, WT_INDEX_PID, "columns=(pid)");
if( rc ) {
Debug( LDAP_DEBUG_ANY,
- LDAP_XSTRING(wt_db_open) ": database \"%s\": "
+ "wt_db_open: database \"%s\": "
"cannot create pid index: \"%s\"\n",
be->be_suffix[0].bv_val, wiredtiger_strerror(rc) );
return -1;
}
- rc = session->create(session, WT_INDEX_REVDN, "columns=(revdn)");
+ rc = session->create(session, WT_INDEX_NDN, "columns=(ndn)");
+ if( rc ) {
+ Debug( LDAP_DEBUG_ANY,
+ "wt_db_open: database \"%s\": "
+ "cannot create ndn index: \"%s\"\n",
+ be->be_suffix[0].bv_val, wiredtiger_strerror(rc) );
+ return -1;
+ }
+
+ /* open in-memory database for idlcache */
+ rc = wiredtiger_open(be->be_suffix[0].bv_val, NULL,
+ "in_memory=true", &wi->wi_cache);
+ if( rc ) {
+ Debug( LDAP_DEBUG_ANY,
+ "wt_db_open: database \"%s\": "
+ "cannot open database for cache (%s).\n",
+ be->be_suffix[0].bv_val, wiredtiger_strerror(rc) );
+ return -1;
+ }
+
+ rc = wi->wi_cache->open_session(wi->wi_cache, NULL, NULL, &cache_session);
+ if( rc ) {
+ Debug( LDAP_DEBUG_ANY,
+ "wt_db_open: database \"%s\": "
+ "cannot open session for cache: \"%s\"\n",
+ be->be_suffix[0].bv_val, wiredtiger_strerror(rc) );
+ return -1;
+ }
+
+ rc = cache_session->create(cache_session,
+ WT_TABLE_IDLCACHE,
+ "key_format=Sb,"
+ "value_format=u,"
+ "columns=(ndn,scope,idl)");
if( rc ) {
Debug( LDAP_DEBUG_ANY,
- LDAP_XSTRING(wt_db_open) ": database \"%s\": "
- "cannot create revdn index: \"%s\"\n",
+ "wt_db_open: database \"%s\": "
+ "cannot create idlcache table: \"%s\"\n",
be->be_suffix[0].bv_val, wiredtiger_strerror(rc) );
return -1;
}
+readonly:
rc = wt_last_id( be, session, &wi->wi_lastid);
if (rc) {
snprintf( cr->msg, sizeof(cr->msg), "database \"%s\": "
"last_id() failed: %s(%d).",
be->be_suffix[0].bv_val, wiredtiger_strerror(rc), rc );
- Debug( LDAP_DEBUG_ANY,
- LDAP_XSTRING(wt_db_open) ": %s\n",
- cr->msg );
+ Debug( LDAP_DEBUG_ANY, "wt_db_open: %s\n", cr->msg );
return rc;
}
- session->close(session, NULL);
- wi->wi_conn = conn;
- wi->wi_flags |= WT_IS_OPEN;
+ if (session) {
+ session->close(session, NULL);
+ }
+ if (cache_session) {
+ cache_session->close(cache_session, NULL);
+ }
+ wi->wi_flags |= WT_IS_OPEN;
return LDAP_SUCCESS;
}
struct wt_info *wi = (struct wt_info *) be->be_private;
int rc;
+ if ( !wi->wi_conn ) {
+ return -1;
+ }
+
rc = wi->wi_conn->close(wi->wi_conn, NULL);
if( rc ) {
int saved_errno = errno;
Debug( LDAP_DEBUG_ANY,
- LDAP_XSTRING(wt_db_close)
- ": cannot close database (%d).\n",
- saved_errno );
+ "wt_db_close: cannot close database (%d).\n", saved_errno );
return -1;
}
{
struct wt_info *wi = (struct wt_info *) be->be_private;
- if( wi->wi_dbenv_home ) {
- ch_free( wi->wi_dbenv_home );
- wi->wi_dbenv_home = NULL;
+ if( wi->wi_home ) {
+ ch_free( wi->wi_home );
+ wi->wi_home = NULL;
}
- if( wi->wi_dbenv_config ) {
- ch_free( wi->wi_dbenv_config );
- wi->wi_dbenv_config = NULL;
+
+ if( wi->wi_config ) {
+ ch_free( wi->wi_config );
+ wi->wi_config = NULL;
}
wt_attr_index_destroy( wi );
int
wt_back_initialize( BackendInfo *bi )
{
- static char *controls[] = {
+ static const char *controls[] = {
LDAP_CONTROL_ASSERT,
LDAP_CONTROL_MANAGEDSAIT,
LDAP_CONTROL_NOOP,
LDAP_CONTROL_POST_READ,
LDAP_CONTROL_SUBENTRIES,
LDAP_CONTROL_X_PERMISSIVE_MODIFY,
+#ifdef LDAP_X_TXN
+ LDAP_CONTROL_X_TXN_SPEC,
+#endif
NULL
};
/* initialize the database system */
Debug( LDAP_DEBUG_TRACE,
- LDAP_XSTRING(wt_back_initialize)
- ": initialize WiredTiger backend\n" );
+ "wt_back_initialize: initialize WiredTiger backend\n" );
bi->bi_flags |=
SLAP_BFLAG_INCREMENT |
SLAP_BFLAG_ALIASES |
SLAP_BFLAG_REFERRALS;
- bi->bi_controls = controls;
-/* version check */
+ bi->bi_controls = (char **)controls;
+
+ /* version check */
Debug( LDAP_DEBUG_TRACE,
- LDAP_XSTRING(wt_back_initialize) ": %s\n",
+ "wt_back_initialize: %s\n",
wiredtiger_version(NULL, NULL, NULL) );
bi->bi_open = 0;
bi->bi_op_search = wt_search;
bi->bi_op_compare = wt_compare;
bi->bi_op_modify = wt_modify;
- bi->bi_op_modrdn = 0;
+ bi->bi_op_modrdn = wt_modrdn;
bi->bi_op_delete = wt_delete;
bi->bi_op_abandon = 0;
- bi->bi_extended = 0;
+ bi->bi_extended = wt_extended;
+#ifdef LDAP_X_TXN
+ bi->bi_op_txn = 0;
+#endif
bi->bi_chk_referrals = 0;
bi->bi_operational = wt_operational;
+ bi->bi_has_subordinates = wt_hasSubordinates;
bi->bi_entry_release_rw = wt_entry_release;
bi->bi_entry_get_rw = wt_entry_get;
bi->bi_tool_entry_get = wt_tool_entry_get;
bi->bi_tool_entry_put = wt_tool_entry_put;
bi->bi_tool_entry_reindex = wt_tool_entry_reindex;
+ bi->bi_tool_sync = 0;
+ bi->bi_tool_dn2id_get = wt_tool_dn2id_get;
+ bi->bi_tool_entry_modify = wt_tool_entry_modify;
+
+#if LDAP_VENDOR_VERSION_MINOR == X || LDAP_VENDOR_VERSION_MINOR >= 5
+ bi->bi_tool_entry_delete = wt_tool_entry_delete;
+#endif
bi->bi_connection_init = 0;
bi->bi_connection_destroy = 0;
wt_key_read(
Backend *be,
WT_CURSOR *cursor,
- struct berval *k,
+ struct berval *bkey,
ID *ids,
WT_CURSOR **saved_cursor,
int get_flag
int exact;
WT_ITEM key2;
ID id;
+ int comp;
+ long scanned = 0;
Debug( LDAP_DEBUG_TRACE, "=> key_read\n" );
WT_IDL_ZERO(ids);
-
- bv2ITEM(k, &key);
+ bv2ITEM(bkey, &key);
cursor->set_key(cursor, &key, 0);
rc = cursor->search_near(cursor, &exact);
- if( rc ){
+ switch( rc ){
+ case 0:
+ break;
+ case WT_NOTFOUND:
+ rc = LDAP_SUCCESS;
+ goto done;
+ default:
Debug( LDAP_DEBUG_ANY,
- LDAP_XSTRING(wt_key_read)
- ": search_near failed: %s (%d)\n",
- wiredtiger_strerror(rc), rc );
+ "wt_key_read: search_near failed: %s (%d)\n",
+ wiredtiger_strerror(rc), rc);
goto done;
}
-
do {
+ scanned++;
rc = cursor->get_key(cursor, &key2, &id);
if( rc ){
Debug( LDAP_DEBUG_ANY,
- LDAP_XSTRING(wt_key_read)
- ": get_key failed: %s (%d)\n",
+ "wt_key_read: get_key failed: %s (%d)\n",
wiredtiger_strerror(rc), rc );
break;
}
-
- if (key.size != key2.size || memcmp(key.data, key2.data, key.size)) {
+ comp = 0;
+ if (key.size != key2.size ||
+ (comp = memcmp(key2.data, key.data, key.size))) {
+ if(comp > 0){
+ break;
+ }
if(exact < 0){
rc = cursor->next(cursor);
if (rc) {
rc = cursor->next(cursor);
} while(rc == 0);
- if (rc == WT_NOTFOUND ) {
+ if ( rc == WT_NOTFOUND && exact == 0 ) {
rc = LDAP_SUCCESS;
}
done:
if( rc != LDAP_SUCCESS ) {
- Debug( LDAP_DEBUG_TRACE, "<= wt_key_read: failed (%d)\n",
- rc );
+ Debug( LDAP_DEBUG_TRACE, "<= wt_key_read: failed (%d) %ld scanned\n",
+ rc, scanned );
} else {
- Debug( LDAP_DEBUG_TRACE, "<= wt_key_read %ld candidates\n",
- (long) WT_IDL_N(ids) );
+ Debug( LDAP_DEBUG_TRACE, "<= wt_key_read %ld candidates %ld scanned\n",
+ (long) WT_IDL_N(ids), scanned );
}
return rc;
if ( rc == WT_NOTFOUND ) rc = 0;
}
if( rc ) {
- Debug( LDAP_DEBUG_ANY,
- LDAP_XSTRING(wt_key_change)
- ": error: %s (%d)\n",
- wiredtiger_strerror(rc), rc );
+ if ( rc != WT_ROLLBACK ) {
+ Debug( LDAP_DEBUG_ANY,
+ "wt_key_change: error: %s (%d)\n",
+ wiredtiger_strerror(rc), rc);
+ }
return rc;
}
* Public License.
*
* A copy of this license is available in the file LICENSE in the
- * top-level directory of the distribution or, alternatively, at
+B * top-level directory of the distribution or, alternatively, at
* <http://www.OpenLDAP.org/license.html>.
*/
/* ACKNOWLEDGEMENTS:
#include "portable.h"
#include <stdio.h>
+#include <ac/string.h>
#include "back-wt.h"
#include "slap-config.h"
break;
}
- Debug(LDAP_DEBUG_ARGS,
+ Debug( LDAP_DEBUG_ARGS,
"wt_modify_internal: delete %s\n",
mod->sm_desc->ad_cname.bv_val );
err = modify_delete_values( e, mod, get_permissiveModify(op),
break;
case LDAP_MOD_REPLACE:
- Debug(LDAP_DEBUG_ARGS,
+ Debug( LDAP_DEBUG_ARGS,
"wt_modify_internal: replace %s\n",
mod->sm_desc->ad_cname.bv_val );
err = modify_replace_values( e, mod, get_permissiveModify(op),
break;
case LDAP_MOD_INCREMENT:
- Debug(LDAP_DEBUG_ARGS,
+ Debug( LDAP_DEBUG_ARGS,
"wt_modify_internal: increment %s\n",
mod->sm_desc->ad_cname.bv_val );
err = modify_increment_values( e, mod, get_permissiveModify(op),
text, textbuf, textlen );
if( err != LDAP_SUCCESS ) {
- Debug(LDAP_DEBUG_ARGS,
- "wt_modify_internal: %d %s\n",
- err, *text );
+ Debug( LDAP_DEBUG_ARGS,
+ "wt_modify_internal: %d %s\n", err, *text );
} else {
got_delete = 1;
}
break;
case SLAP_MOD_SOFTADD:
- Debug(LDAP_DEBUG_ARGS,
+ Debug( LDAP_DEBUG_ARGS,
"wt_modify_internal: softadd %s\n",
mod->sm_desc->ad_cname.bv_val );
/* Avoid problems in index_add_mods()
break;
case SLAP_MOD_SOFTDEL:
- Debug(LDAP_DEBUG_ARGS,
+ Debug( LDAP_DEBUG_ARGS,
"wt_modify_internal: softdel %s\n",
mod->sm_desc->ad_cname.bv_val );
/* Avoid problems in index_delete_mods()
if ( rc != LDAP_SUCCESS ) {
Debug( LDAP_DEBUG_ANY,
- "entry failed schema check: %s\n",
- *text );
+ "entry failed schema check: %s\n", *text );
}
/* if NOOP then silently revert to saved attrs */
{
struct wt_info *wi = (struct wt_info *) op->o_bd->be_private;
wt_ctx *wc = NULL;
- Entry *e = NULL;
+ Entry *e = NULL;
int manageDSAit = get_manageDSAit( op );
char textbuf[SLAP_TEXT_BUFLEN];
size_t textlen = sizeof textbuf;
int rc;
- Debug( LDAP_DEBUG_ARGS, LDAP_XSTRING(wt_modify) ": %s\n",
- op->o_req_dn.bv_val );
+ Debug( LDAP_DEBUG_ARGS, "wt_modify: %s\n", op->o_req_dn.bv_val );
+#ifdef LDAP_X_TXN
if( op->o_txnSpec && txn_preop( op, rs ))
return rs->sr_err;
+#endif
ctrls[num_ctrls] = NULL;
wc = wt_ctx_get(op, wi);
if( !wc ){
- Debug( LDAP_DEBUG_ANY,
- LDAP_XSTRING(wt_add)
- ": wt_ctx_get failed\n" );
+ Debug( LDAP_DEBUG_ANY, "wt_modify: wt_ctx_get failed\n" );
rs->sr_err = LDAP_OTHER;
rs->sr_text = "internal error";
send_ldap_result( op, rs );
slap_mods_opattrs( op, &op->orm_modlist, 1 );
}
+retry:
+ /* begin transaction */
+ wc->is_begin_transaction = 0;
+ rc = wc->session->begin_transaction(wc->session, "isolation=snapshot");
+ if( rc ) {
+ Debug( LDAP_DEBUG_TRACE,
+ "wt_modify: begin_transaction failed: %s (%d)\n",
+ wiredtiger_strerror(rc), rc );
+ rs->sr_err = LDAP_OTHER;
+ rs->sr_text = "begin_transaction failed";
+ goto return_results;
+ }
+ wc->is_begin_transaction = 1;
+ Debug( LDAP_DEBUG_TRACE, "wt_modify: session id: %p\n", wc->session );
+
/* get entry */
rc = wt_dn2entry(op->o_bd, wc, &op->o_req_ndn, &e);
switch( rc ) {
case 0:
break;
case WT_NOTFOUND:
- Debug( LDAP_DEBUG_ARGS,
- "<== " LDAP_XSTRING(wt_delete)
- ": no such object %s\n",
- op->o_req_dn.bv_val );
- /* TODO: lookup referrals */
- rs->sr_err = LDAP_NO_SUCH_OBJECT;
- goto return_results;
+ break;
default:
Debug( LDAP_DEBUG_ANY,
- LDAP_XSTRING(wt_modify)
- ": wt_dn2entry failed (%d)\n",
- rc );
+ "<== wt_modify: wt_dn2entry failed (%d)\n", rc );
rs->sr_err = LDAP_OTHER;
rs->sr_text = "internal error";
goto return_results;
}
+ if ( rc == WT_NOTFOUND ||
+ ( !manageDSAit && e && is_entry_glue( e ))) {
+ if ( !e ) {
+ rc = wt_dn2aentry(op->o_bd, wc, &op->o_req_ndn, &e);
+ switch( rc ) {
+ case 0:
+ break;
+ case WT_NOTFOUND:
+ rs->sr_err = LDAP_NO_SUCH_OBJECT;
+ goto return_results;
+ default:
+ Debug( LDAP_DEBUG_ANY, "wt_modify: wt_dna2entry failed (%d)\n", rc );
+ rs->sr_err = LDAP_OTHER;
+ rs->sr_text = "internal error";
+ goto return_results;
+ }
+ }
+
+ rs->sr_matched = ch_strdup( e->e_dn );
+
+ if ( is_entry_referral( e ) ) {
+ BerVarray ref = get_entry_referrals( op, e );
+ rs->sr_ref = referral_rewrite( ref, &e->e_name,
+ &op->o_req_dn, LDAP_SCOPE_DEFAULT );
+ ber_bvarray_free( ref );
+ } else {
+ rs->sr_ref = NULL;
+ }
+ rs->sr_flags = REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED;
+ rs->sr_err = LDAP_REFERRAL;
+ send_ldap_result( op, rs );
+ goto done;
+ }
+
if ( !manageDSAit && is_entry_referral( e ) ) {
/* entry is a referral, don't allow modify */
rs->sr_ref = get_entry_referrals( op, e );
- Debug( LDAP_DEBUG_TRACE,
- LDAP_XSTRING(wt_modify) ": entry is referral\n" );
+ Debug( LDAP_DEBUG_TRACE, "wt_modify: entry is referral\n" );
rs->sr_err = LDAP_REFERRAL;
rs->sr_matched = e->e_name.bv_val;
&slap_pre_read_bv, preread_ctrl ) )
{
Debug( LDAP_DEBUG_TRACE,
- "<=- " LDAP_XSTRING(wt_modify) ": pre-read "
- "failed!\n" );
+ "<=- wt_modify: pre-read failed!\n" );
if ( op->o_preread & SLAP_CONTROL_CRITICAL ) {
/* FIXME: is it correct to abort
* operation if control fails? */
}
}
- /* begin transaction */
- rc = wc->session->begin_transaction(wc->session, NULL);
- if( rc ) {
- Debug( LDAP_DEBUG_TRACE,
- LDAP_XSTRING(wt_add) ": begin_transaction failed: %s (%d)\n",
- wiredtiger_strerror(rc), rc );
- rs->sr_err = LDAP_OTHER;
- rs->sr_text = "begin_transaction failed";
- goto return_results;
- }
- Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(wt_modify) ": session id: %p\n",
- wc->session );
-
/* Modify the entry */
dummy = *e;
rs->sr_err = wt_modify_internal( op, wc, op->orm_modlist,
&dummy, &rs->sr_text, textbuf, textlen );
- if( rs->sr_err != LDAP_SUCCESS ) {
- Debug( LDAP_DEBUG_TRACE,
- LDAP_XSTRING(wt_modify) ": modify failed (%d)\n",
- rs->sr_err );
+ switch ( rs->sr_err ) {
+ case LDAP_SUCCESS:
+ break;
+ case WT_ROLLBACK:
+ Debug (LDAP_DEBUG_TRACE, "wt_modify: rollback wt_modify_internal failed.\n" );
+ wc->session->rollback_transaction(wc->session, NULL);
+ goto retry;
+ default:
+ Debug( LDAP_DEBUG_ANY, "wt_modify: modify failed (%d)\n", rs->sr_err );
/* Only free attrs if they were dup'd. */
if ( dummy.e_attrs == e->e_attrs ) dummy.e_attrs = NULL;
goto return_results;
}
/* change the entry itself */
- rs->sr_err = wt_id2entry_update( op, wc->session, &dummy );
- if ( rs->sr_err != 0 ) {
- Debug( LDAP_DEBUG_TRACE,
- LDAP_XSTRING(wt_modify) ": id2entry update failed " "(%d)\n",
- rs->sr_err );
- if ( rs->sr_err == LDAP_ADMINLIMIT_EXCEEDED ) {
- rs->sr_text = "entry too big";
- } else {
- rs->sr_err = LDAP_OTHER;
- rs->sr_text = "entry update failed";
- }
+ rs->sr_err = wt_id2entry_update( op, wc, &dummy );
+ switch ( rs->sr_err ) {
+ case 0:
+ break;
+ case WT_ROLLBACK:
+ Debug (LDAP_DEBUG_TRACE, "wt_modify: rollback wt_id2entry_update failed.\n");
+ wc->session->rollback_transaction(wc->session, NULL);
+ goto retry;
+ case LDAP_ADMINLIMIT_EXCEEDED:
+ Debug( LDAP_DEBUG_ANY, "wt_modify: id2entry update failed (%d)\n",
+ rs->sr_err);
+ rs->sr_text = "entry too big";
+ goto return_results;
+ default:
+ Debug( LDAP_DEBUG_ANY, "wt_modify: id2entry update failed (%d)\n",
+ rs->sr_err);
+ rs->sr_err = LDAP_OTHER;
+ rs->sr_text = "entry update failed";
goto return_results;
}
+ if( op->o_postread ) {
+ if( postread_ctrl == NULL ) {
+ postread_ctrl = &ctrls[num_ctrls++];
+ ctrls[num_ctrls] = NULL;
+ }
+ if( slap_read_controls( op, rs, &dummy,
+ &slap_post_read_bv, postread_ctrl ) )
+ {
+ Debug( LDAP_DEBUG_TRACE,
+ "<== wt_modify: post-read failed!\n");
+ if ( op->o_postread & SLAP_CONTROL_CRITICAL ) {
+ /* FIXME: is it correct to abort
+ * operation if control fails? */
+ goto return_results;
+ }
+ }
+ }
+
if( op->o_noop ) {
- wc->session->rollback_transaction(wc->session, NULL);
rs->sr_err = LDAP_X_NO_OPERATION;
goto return_results;
}
if ( dummy.e_attrs == e->e_attrs ) dummy.e_attrs = NULL;
rc = wc->session->commit_transaction(wc->session, NULL);
+ wc->is_begin_transaction = 0;
if( rc ) {
Debug( LDAP_DEBUG_TRACE,
- "<== " LDAP_XSTRING(wt_modify)
- ": commit failed: %s (%d)\n",
+ "<== wt_modify: commit failed: %s (%d)\n",
wiredtiger_strerror(rc), rc );
rs->sr_err = LDAP_OTHER;
rs->sr_text = "commit failed";
}
Debug( LDAP_DEBUG_TRACE,
- LDAP_XSTRING(wt_modify) ": updated%s id=%08lx dn=\"%s\"\n",
+ "wt_modify: updated%s id=%08lx dn=\"%s\"\n",
op->o_noop ? " (no-op)" : "",
dummy.e_id, op->o_req_dn.bv_val );
- if( op->o_postread ) {
- if( postread_ctrl == NULL ) {
- postread_ctrl = &ctrls[num_ctrls++];
- ctrls[num_ctrls] = NULL;
- }
- if( slap_read_controls( op, rs, &dummy,
- &slap_post_read_bv, postread_ctrl ) )
- {
- Debug( LDAP_DEBUG_TRACE,
- "<=- " LDAP_XSTRING(wt_modify)
- ": post-read failed!\n" );
- if ( op->o_postread & SLAP_CONTROL_CRITICAL ) {
- /* FIXME: is it correct to abort
- * operation if control fails? */
- goto return_results;
- }
- }
- }
- if( num_ctrls ) rs->sr_ctrls = ctrls;
-
rs->sr_err = LDAP_SUCCESS;
rs->sr_text = NULL;
+ if( num_ctrls ) rs->sr_ctrls = ctrls;
return_results:
if( dummy.e_attrs ) {
done:
slap_graduate_commit_csn( op );
+ if( wc && wc->is_begin_transaction ){
+ Debug( LDAP_DEBUG_TRACE, "wt_modify: rollback transaction\n" );
+ wc->session->rollback_transaction(wc->session, NULL);
+ wc->is_begin_transaction = 0;
+ }
+
if( e != NULL ) {
wt_entry_return( e );
}
slap_sl_free( *postread_ctrl, op->o_tmpmemctx );
}
- rs->sr_text = NULL;
-
return rs->sr_err;
}
--- /dev/null
+/* OpenLDAP WiredTiger backend */
+/* $OpenLDAP$ */
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
+ *
+ * Copyright 2002-2015 The OpenLDAP Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted only as authorized by the OpenLDAP
+ * Public License.
+ *
+ * A copy of this license is available in the file LICENSE in the
+ * top-level directory of the distribution or, alternatively, at
+ * <http://www.OpenLDAP.org/license.html>.
+ */
+/* ACKNOWLEDGEMENTS:
+ * This work was developed by HAMANO Tsukasa <hamano@osstech.co.jp>
+ * based on back-bdb for inclusion in OpenLDAP Software.
+ * WiredTiger is a product of MongoDB Inc.
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+#include "back-wt.h"
+#include "slap-config.h"
+
+int
+wt_modrdn( Operation *op, SlapReply *rs )
+{
+ struct wt_info *wi = (struct wt_info *) op->o_bd->be_private;
+ AttributeDescription *children = slap_schema.si_ad_children;
+ AttributeDescription *entry = slap_schema.si_ad_entry;
+ wt_ctx *wc = NULL;
+ Entry *e = NULL;
+ Entry *p = NULL;
+ Entry *ne = NULL;
+ Entry dummy = {0};
+
+ struct berval p_dn, p_ndn;
+ struct berval new_dn = {0, NULL}, new_ndn = {0, NULL};
+
+ Entry *np = NULL; /* newSuperior Entry */
+ struct berval *np_dn = NULL; /* newSuperior dn */
+ struct berval *np_ndn = NULL; /* newSuperior ndn */
+ struct berval *new_parent_dn = NULL; /* np_dn, p_dn, or NULL */
+
+ int manageDSAit = get_manageDSAit( op );
+ char textbuf[SLAP_TEXT_BUFLEN];
+ size_t textlen = sizeof textbuf;
+ LDAPControl **preread_ctrl = NULL;
+ LDAPControl **postread_ctrl = NULL;
+ LDAPControl *ctrls[SLAP_MAX_RESPONSE_CONTROLS];
+ int num_ctrls = 0;
+
+ int rc;
+
+ int parent_is_glue = 0;
+ int parent_is_leaf = 0;
+
+ Debug( LDAP_DEBUG_TRACE, "==> wt_modrdn(%s -> newrdn=%s - newsup=%s)\n",
+ op->o_req_dn.bv_val,
+ op->oq_modrdn.rs_newrdn.bv_val,
+ op->oq_modrdn.rs_newSup?op->oq_modrdn.rs_newSup->bv_val:"NULL" );
+
+ ctrls[num_ctrls] = NULL;
+
+ slap_mods_opattrs( op, &op->orr_modlist, 1 );
+
+ wc = wt_ctx_get(op, wi);
+ if( !wc ){
+ Debug( LDAP_DEBUG_ANY, "wt_modrdn: wt_ctx_get failed\n");
+ rs->sr_err = LDAP_OTHER;
+ rs->sr_text = "internal error";
+ send_ldap_result( op, rs );
+ return rs->sr_err;
+ }
+
+ /* get parent entry */
+ if ( be_issuffix( op->o_bd, &op->o_req_ndn ) ) {
+ rs->sr_err = LDAP_NAMING_VIOLATION;
+ rs->sr_text = "cannot rename suffix entry";
+ goto return_results;
+ } else {
+ dnParent( &op->o_req_ndn, &p_ndn );
+ }
+
+ rc = wt_dn2entry(op->o_bd, wc, &p_ndn, &p);
+ switch( rc ) {
+ case 0:
+ break;
+ case WT_NOTFOUND:
+ Debug( LDAP_DEBUG_ARGS,
+ "<== wt_modrdn: parent does not exist %s\n", p_ndn.bv_val);
+ rs->sr_err = LDAP_NO_SUCH_OBJECT;
+ goto return_results;
+ default:
+ Debug( LDAP_DEBUG_ANY,
+ "<== wt_modrdn: wt_dn2entry failed (%d)\n", rc );
+ rs->sr_err = LDAP_OTHER;
+ rs->sr_text = "internal error";
+ goto return_results;
+ }
+
+ /* check parent for "children" acl */
+ rc = access_allowed( op, p, children, NULL,
+ op->oq_modrdn.rs_newSup == NULL ?
+ ACL_WRITE : ACL_WDEL, NULL );
+
+ if ( !rc ) {
+ rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
+ Debug( LDAP_DEBUG_TRACE,
+ "wt_modrdn: no access to parent\n");
+ rs->sr_text = "no write access to old parent's children";
+ goto return_results;
+ }
+
+ Debug( LDAP_DEBUG_TRACE,
+ "wt_modrdn: wr to children of entry %s OK\n", p_ndn.bv_val );
+
+ if ( p_ndn.bv_val == slap_empty_bv.bv_val ) {
+ p_dn = slap_empty_bv;
+ } else {
+ dnParent( &op->o_req_dn, &p_dn );
+ }
+
+ Debug( LDAP_DEBUG_TRACE,
+ "wt_modrdn: parent dn=%s\n", p_dn.bv_val );
+
+ /* get entry */
+ rc = wt_dn2entry(op->o_bd, wc, &op->o_req_ndn, &e);
+ switch( rc ) {
+ case 0:
+ break;
+ case WT_NOTFOUND:
+ break;
+ default:
+ Debug( LDAP_DEBUG_ANY,
+ "<== wt_modrdn: wt_dn2entry failed (%d)\n", rc );
+ rs->sr_err = LDAP_OTHER;
+ rs->sr_text = "internal error";
+ goto return_results;
+ }
+
+ if ( rc == WT_NOTFOUND ||
+ ( !manageDSAit && e && is_entry_glue( e ) )) {
+
+ if ( !e ) {
+ Debug( LDAP_DEBUG_ARGS,
+ "<== wt_modrdn: no such object %s\n", op->o_req_dn.bv_val);
+ rc = wt_dn2aentry(op->o_bd, wc, &op->o_req_ndn, &e);
+ switch( rc ) {
+ case 0:
+ break;
+ case WT_NOTFOUND:
+ rs->sr_err = LDAP_NO_SUCH_OBJECT;
+ goto return_results;
+ default:
+ Debug( LDAP_DEBUG_ANY, "wt_modrdn: wt_dn2aentry failed (%d)\n", rc );
+ rs->sr_err = LDAP_OTHER;
+ rs->sr_text = "internal error";
+ goto return_results;
+ }
+ }
+
+ rs->sr_matched = ch_strdup( e->e_dn );
+
+ if ( is_entry_referral( e ) ) {
+ BerVarray ref = get_entry_referrals( op, e );
+ rs->sr_ref = referral_rewrite( ref, &e->e_name,
+ &op->o_req_dn, LDAP_SCOPE_DEFAULT );
+ ber_bvarray_free( ref );
+ } else {
+ rs->sr_ref = NULL;
+ }
+ rs->sr_flags = REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED;
+ rs->sr_err = LDAP_REFERRAL;
+ send_ldap_result( op, rs );
+ goto done;
+ }
+
+ if ( get_assert( op ) &&
+ ( test_filter( op, e, get_assertion( op )) != LDAP_COMPARE_TRUE ))
+ {
+ rs->sr_err = LDAP_ASSERTION_FAILED;
+ goto return_results;
+ }
+
+ /* check write on old entry */
+ rc = access_allowed( op, e, entry, NULL, ACL_WRITE, NULL );
+ if ( !rc ) {
+ Debug( LDAP_DEBUG_TRACE, "wt_modrdn: no access to entry\n");
+ rs->sr_text = "no write access to old entry";
+ rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
+ goto return_results;
+ }
+
+ /* Can't do it if we have kids */
+ rc = wt_dn2id_has_children( op, wc, e->e_id );
+ if( rc != WT_NOTFOUND ) {
+ switch( rc ) {
+ case 0:
+ Debug(LDAP_DEBUG_ARGS, "<== wt_modrdn: non-leaf %s\n", op->o_req_dn.bv_val);
+ rs->sr_err = LDAP_NOT_ALLOWED_ON_NONLEAF;
+ rs->sr_text = "subtree rename not supported";
+ break;
+ default:
+ Debug(LDAP_DEBUG_ARGS,
+ "<== wt_modrdn: has_children failed: %s (%d)\n",
+ wiredtiger_strerror(rc), rc );
+ rs->sr_err = LDAP_OTHER;
+ rs->sr_text = "internal error";
+ }
+ goto return_results;
+ }
+
+ if (!manageDSAit && is_entry_referral( e ) ) {
+ /* parent is a referral, don't allow add */
+ rs->sr_ref = get_entry_referrals( op, e );
+
+ Debug( LDAP_DEBUG_TRACE,
+ "wt_modrdn: entry %s is referral\n", e->e_dn );
+
+ rs->sr_err = LDAP_REFERRAL,
+ rs->sr_matched = e->e_name.bv_val;
+ send_ldap_result( op, rs );
+
+ ber_bvarray_free( rs->sr_ref );
+ rs->sr_ref = NULL;
+ rs->sr_matched = NULL;
+ goto done;
+ }
+
+ new_parent_dn = &p_dn; /* New Parent unless newSuperior given */
+ if ( op->oq_modrdn.rs_newSup != NULL ) {
+ Debug( LDAP_DEBUG_TRACE,
+ "wt_modrdn: new parent \"%s\" requested...\n",
+ op->oq_modrdn.rs_newSup->bv_val );
+
+ /* newSuperior == oldParent? */
+ if( dn_match( &p_ndn, op->oq_modrdn.rs_nnewSup ) ) {
+ Debug( LDAP_DEBUG_TRACE,
+ "wt_modrdn: new parent \"%s\" same as the old parent \"%s\"\n",
+ op->oq_modrdn.rs_newSup->bv_val, p_dn.bv_val );
+ op->oq_modrdn.rs_newSup = NULL; /* ignore newSuperior */
+ }
+ }
+
+ if ( op->oq_modrdn.rs_newSup != NULL ) {
+ if ( op->oq_modrdn.rs_newSup->bv_len ) {
+ np_dn = op->oq_modrdn.rs_newSup;
+ np_ndn = op->oq_modrdn.rs_nnewSup;
+
+ /* newSuperior == oldParent? - checked above */
+ /* newSuperior == entry being moved?, if so ==> ERROR */
+ if ( dnIsSuffix( np_ndn, &e->e_nname )) {
+ rs->sr_err = LDAP_NO_SUCH_OBJECT;
+ rs->sr_text = "new superior not found";
+ goto return_results;
+ }
+ /* Get Entry with dn=newSuperior. Does newSuperior exist? */
+ rc = wt_dn2entry(op->o_bd, wc, np_ndn, &np);
+ switch( rc ) {
+ case 0:
+ break;
+ case WT_NOTFOUND:
+ Debug( LDAP_DEBUG_ANY,
+ "<== wt_modrdn: new superior not found: %s\n",
+ np_ndn->bv_val );
+ rs->sr_err = LDAP_NO_SUCH_OBJECT;
+ rs->sr_text = "new superior not found";
+ goto return_results;
+ default:
+ Debug( LDAP_DEBUG_ANY,
+ "<== wt_modrdn: wt_dn2entry failed %s (%d)\n",
+ wiredtiger_strerror(rc), rc );
+ rs->sr_err = LDAP_OTHER;
+ rs->sr_text = "internal error";
+ goto return_results;
+ }
+ Debug( LDAP_DEBUG_TRACE,
+ "wt_modrdn: wr to new parent OK np=%p, id=%ld\n",
+ (void *) np, (long) np->e_id );
+ rs->sr_err = access_allowed( op, np, children,
+ NULL, ACL_WADD, NULL );
+ if( ! rs->sr_err ) {
+ Debug( LDAP_DEBUG_TRACE,
+ "wt_modrdn: no wr to newSup children\n" );
+ rs->sr_text = "no write access to new superior's children";
+ rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
+ goto return_results;
+ }
+ if ( is_entry_alias( np ) ) {
+ Debug( LDAP_DEBUG_TRACE,
+ "wt_modrdn: entry is alias\n" );
+ rs->sr_text = "new superior is an alias";
+ rs->sr_err = LDAP_ALIAS_PROBLEM;
+ goto return_results;
+ }
+ if ( is_entry_referral( np ) ) {
+ /* parent is a referral, don't allow add */
+ Debug( LDAP_DEBUG_TRACE,
+ "wt_modrdn: entry is referral\n" );
+ rs->sr_text = "new superior is a referral";
+ rs->sr_err = LDAP_OTHER;
+ goto return_results;
+ }
+ } else {
+ /* no parent, modrdn entry directly under root */
+ /* TODO: */
+ Debug( LDAP_DEBUG_TRACE,
+ "wt_modrdn: no parent, not implement yet\n" );
+ rs->sr_text = "not implement yet";
+ rs->sr_err = LDAP_OTHER;
+ goto return_results;
+ }
+
+ Debug( LDAP_DEBUG_TRACE,
+ "wt_modrdn: wr to new parent's children OK\n" );
+ new_parent_dn = np_dn;
+ }
+
+ /* Build target dn and make sure target entry doesn't exist already. */
+ if (!new_dn.bv_val) {
+ build_new_dn( &new_dn, new_parent_dn, &op->oq_modrdn.rs_newrdn, NULL );
+ }
+
+ if (!new_ndn.bv_val) {
+ struct berval bv = {0, NULL};
+ dnNormalize( 0, NULL, NULL, &new_dn, &bv, op->o_tmpmemctx );
+ ber_dupbv( &new_ndn, &bv );
+ /* FIXME: why not call dnNormalize() w/o ctx? */
+ op->o_tmpfree( bv.bv_val, op->o_tmpmemctx );
+ }
+
+ Debug( LDAP_DEBUG_TRACE,
+ "wt_modrdn: new ndn=%s\n", new_ndn.bv_val );
+
+ /* check new entry */
+ rc = wt_dn2entry(op->o_bd, wc, &new_ndn, &ne);
+ switch( rc ) {
+ case 0:
+ /* Allow rename to same DN */
+ if(e->e_id == ne->e_id){
+ break;
+ }
+ rs->sr_err = LDAP_ALREADY_EXISTS;
+ goto return_results;
+ break;
+ case WT_NOTFOUND:
+ break;
+ default:
+ Debug( LDAP_DEBUG_ANY,
+ "<== wt_modrdn: wt_dn2entry failed %s (%d)\n",
+ wiredtiger_strerror(rc), rc );
+ rs->sr_err = LDAP_OTHER;
+ rs->sr_text = "internal error";
+ goto return_results;
+ }
+
+ assert( op->orr_modlist != NULL );
+
+ if( op->o_preread ) {
+ if( preread_ctrl == NULL ) {
+ preread_ctrl = &ctrls[num_ctrls++];
+ ctrls[num_ctrls] = NULL;
+ }
+ if( slap_read_controls( op, rs, e,
+ &slap_pre_read_bv, preread_ctrl ) )
+ {
+ Debug( LDAP_DEBUG_TRACE,
+ "<== wt_modrdn: pre-read failed!\n" );
+ if ( op->o_preread & SLAP_CONTROL_CRITICAL ) {
+ /* FIXME: is it correct to abort
+ * operation if control fails? */
+ goto return_results;
+ }
+ }
+ }
+
+ /* begin transaction */
+ rc = wc->session->begin_transaction(wc->session, NULL);
+ if( rc ) {
+ Debug( LDAP_DEBUG_TRACE,
+ "wt_modrdn: begin_transaction failed: %s (%d)\n",
+ wiredtiger_strerror(rc), rc );
+ rs->sr_err = LDAP_OTHER;
+ rs->sr_text = "begin_transaction failed";
+ goto return_results;
+ }
+ wc->is_begin_transaction = 1;
+ Debug( LDAP_DEBUG_TRACE,
+ "wt_modrdn: session id: %p\n", wc->session );
+
+ /* delete old DN */
+ rc = wt_dn2id_delete( op, wc, &e->e_nname);
+ if ( rc ) {
+ Debug(LDAP_DEBUG_TRACE,
+ "<== wt_modrdn: delete failed: %s (%d)\n",
+ wiredtiger_strerror(rc), rc );
+ rs->sr_err = LDAP_OTHER;
+ rs->sr_text = "dn2id delete failed";
+ goto return_results;
+ }
+
+ /* 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 DN */
+ rc = wt_dn2id_add( op, wc, np?np->e_id:p->e_id, &dummy );
+ if ( rc ) {
+ Debug(LDAP_DEBUG_TRACE,
+ "<== wt_modrdn: add failed: %s (%d)\n",
+ wiredtiger_strerror(rc), rc );
+ rs->sr_err = LDAP_OTHER;
+ rs->sr_text = "DN add failed";
+ goto return_results;
+ }
+ dummy.e_attrs = e->e_attrs;
+
+ rc = wt_modify_internal( op, wc, op->orm_modlist,
+ &dummy, &rs->sr_text, textbuf, textlen );
+ if( rc != LDAP_SUCCESS ) {
+ Debug(LDAP_DEBUG_TRACE,
+ "<== wt_modrdn: modify failed: %s (%d)\n",
+ wiredtiger_strerror(rc), rc );
+ if ( dummy.e_attrs == e->e_attrs ) dummy.e_attrs = NULL;
+ goto return_results;
+ }
+
+ /* update entry */
+ rc = wt_id2entry_update( op, wc, &dummy );
+ if ( rc != 0 ) {
+ Debug( LDAP_DEBUG_TRACE,
+ "wt_modrdn: id2entry update failed(%d)\n", rc );
+ if ( rc == LDAP_ADMINLIMIT_EXCEEDED ) {
+ rs->sr_text = "entry too big";
+ } else {
+ rs->sr_err = LDAP_OTHER;
+ rs->sr_text = "entry update failed";
+ }
+ goto return_results;
+ }
+
+ if ( p_ndn.bv_len != 0 ) {
+ parent_is_glue = is_entry_glue(p);
+ /* TODO: glue entry handling */
+ }
+
+ if( op->o_postread ) {
+ if( postread_ctrl == NULL ) {
+ postread_ctrl = &ctrls[num_ctrls++];
+ ctrls[num_ctrls] = NULL;
+ }
+ if( slap_read_controls( op, rs, &dummy,
+ &slap_post_read_bv, postread_ctrl ) )
+ {
+ Debug( LDAP_DEBUG_TRACE,
+ "<== wt_modrdn: post-read failed!\n" );
+ if ( op->o_postread & SLAP_CONTROL_CRITICAL ) {
+ /* FIXME: is it correct to abort
+ * operation if control fails? */
+ goto return_results;
+ }
+ }
+ }
+
+ if( op->o_noop ) {
+ rs->sr_err = LDAP_X_NO_OPERATION;
+ goto return_results;
+ }
+
+ rc = wc->session->commit_transaction(wc->session, NULL);
+ wc->is_begin_transaction = 0;
+ if( rc ) {
+ Debug( LDAP_DEBUG_TRACE,
+ "<== wt_modrdn: commit failed: %s (%d)\n",
+ wiredtiger_strerror(rc), rc );
+ rs->sr_err = LDAP_OTHER;
+ rs->sr_text = "commit failed";
+ goto return_results;
+ }
+
+ Debug(LDAP_DEBUG_TRACE,
+ "wt_modrdn: rdn modified%s id=%08lx dn=\"%s\"\n",
+ op->o_noop ? " (no-op)" : "",
+ dummy.e_id, op->o_req_dn.bv_val );
+
+ rs->sr_err = LDAP_SUCCESS;
+ rs->sr_text = NULL;
+ 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 && parent_is_glue && parent_is_leaf ) {
+ op->o_delete_glue_parent = 1;
+ }
+
+done:
+ if( wc && wc->is_begin_transaction ){
+ Debug( LDAP_DEBUG_TRACE, "wt_modrdn: rollback transaction\n" );
+ wc->session->rollback_transaction(wc->session, NULL);
+ wc->is_begin_transaction = 0;
+ }
+
+ slap_graduate_commit_csn( op );
+
+ if( new_dn.bv_val != NULL ) free( new_dn.bv_val );
+ if( new_ndn.bv_val != NULL ) free( new_ndn.bv_val );
+
+ /* free entry */
+ if( e != NULL ) {
+ wt_entry_return( e );
+ }
+ /* free parent entry */
+ if( p != NULL ) {
+ wt_entry_return( p );
+ }
+ /* free new entry */
+ if( ne != NULL ) {
+ wt_entry_return( ne );
+ }
+ /* free new parent entry */
+ if( np != NULL ) {
+ wt_entry_return( np );
+ }
+
+ if( preread_ctrl != NULL && (*preread_ctrl) != NULL ) {
+ slap_sl_free( (*preread_ctrl)->ldctl_value.bv_val, op->o_tmpmemctx );
+ slap_sl_free( *preread_ctrl, op->o_tmpmemctx );
+ }
+ if( postread_ctrl != NULL && (*postread_ctrl) != NULL ) {
+ slap_sl_free( (*postread_ctrl)->ldctl_value.bv_val, op->o_tmpmemctx );
+ slap_sl_free( *postread_ctrl, op->o_tmpmemctx );
+ }
+ return rs->sr_err;
+}
+
+/*
+ * Local variables:
+ * indent-tabs-mode: t
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ */
rc = session->open_cursor(session, WT_TABLE_ID2ENTRY, NULL, NULL, &cursor);
if(rc){
Debug( LDAP_DEBUG_ANY,
- LDAP_XSTRING(wt_last_id)
- ": open_cursor failed: %s (%d)\n",
+ "wt_last_id: open_cursor failed: %s (%d)\n",
wiredtiger_strerror(rc), rc );
return rc;
}
rc = cursor->get_key(cursor, &id);
if ( rc ) {
Debug( LDAP_DEBUG_ANY,
- LDAP_XSTRING(wt_last_id)
- ": get_key failed: %s (%d)\n",
+ "wt_last_id: get_key failed: %s (%d)\n",
wiredtiger_strerror(rc), rc );
return rc;
}
break;
default:
Debug( LDAP_DEBUG_ANY,
- LDAP_XSTRING(wt_last_id)
- ": prev failed: %s (%d)\n",
+ "wt_last_id: prev failed: %s (%d)\n",
wiredtiger_strerror(rc), rc );
}
rc = cursor->close(cursor);
if ( rc ) {
Debug( LDAP_DEBUG_ANY,
- LDAP_XSTRING(wt_last_id)
- ": close failed: %s (%d)\n",
+ "wt_last_id: close failed: %s (%d)\n",
wiredtiger_strerror(rc), rc );
return rc;
}
wc = wt_ctx_get(op, wi);
if( !wc ){
Debug( LDAP_DEBUG_ANY,
- LDAP_XSTRING(wt_compare)
- ": wt_ctx_get failed\n" );
+ "wt_hasSubordinates: wt_ctx_get failed\n" );
return LDAP_OTHER;
}
- rc = wt_dn2id_has_children(op, wc->session, e->e_id);
+ rc = wt_dn2id_has_children(op, wc, e->e_id);
switch(rc){
case 0:
*hasSubordinates = LDAP_COMPARE_TRUE;
break;
default:
Debug(LDAP_DEBUG_ANY,
- "<=- " LDAP_XSTRING(wt_hasSubordinates)
- ": has_children failed: %s (%d)\n",
+ "<=- wt_hasSubordinates: has_children failed: %s (%d)\n",
wiredtiger_strerror(rc), rc );
rc = LDAP_OTHER;
}
#define WT_UCTYPE "WT"
+/*
+ * attr.c
+ */
+
AttrInfo *wt_attr_mask( struct wt_info *wi, AttributeDescription *desc );
void wt_attr_flush( struct wt_info *wi );
+void wt_attr_index_unparse( struct wt_info *wi, BerVarray *bva );
+int wt_attr_index_config(
+ struct wt_info *wi,
+ const char *fname,
+ int lineno,
+ int argc,
+ char **argv,
+ struct config_reply_s *c_reply);
+void wt_attr_index_destroy( struct wt_info *wi );
/*
* id2entry.c
*/
-int wt_id2entry_add(Operation *op, WT_SESSION *session, Entry *e );
-int wt_id2entry_update(Operation *op, WT_SESSION *session, Entry *e );
-int wt_id2entry_delete(Operation *op, WT_SESSION *session, Entry *e );
+int wt_id2entry(BackendDB *be, wt_ctx *wc, ID id, Entry **ep );
+int wt_id2entry_add(Operation *op, wt_ctx *wc, Entry *e );
+int wt_id2entry_update(Operation *op, wt_ctx *wc, Entry *e );
+int wt_id2entry_delete(Operation *op, wt_ctx *wc, Entry *e );
BI_entry_release_rw wt_entry_release;
BI_entry_get_rw wt_entry_get;
ID wt_idl_first( ID *ids, ID *cursor );
ID wt_idl_next( ID *ids, ID *cursor );
-
+int wt_idl_append_one( ID *ids, ID id );
+void wt_idl_sort( ID *ids, ID *tmp );
+int wt_idl_intersection( ID *a, ID *b );
+int wt_filter_candidates(
+ Operation *op,
+ wt_ctx *wc,
+ Filter *f,
+ ID *ids,
+ ID *tmp,
+ ID *stack );
+int
+wt_idl_union(
+ ID *a,
+ ID *b );
/*
* index.c
*/
+
+extern AttrInfo *
+wt_index_mask LDAP_P((
+ Backend *be,
+ AttributeDescription *desc,
+ struct berval *atname ));
+
int wt_index_entry LDAP_P(( Operation *op, wt_ctx *wc, int r, Entry *e ));
+int wt_index_values(
+ Operation *op,
+ wt_ctx *wc,
+ AttributeDescription *desc,
+ BerVarray vals,
+ ID id,
+ int opid );
+int wt_index_param(
+ Backend *be,
+ AttributeDescription *desc,
+ int ftype,
+ slap_mask_t *maskp,
+ struct berval *prefixp );
+
+WT_CURSOR *wt_index_open(wt_ctx *wc, struct berval *name, int create);
#define wt_index_entry_add(op,t,e) \
wt_index_entry((op),(t),SLAP_INDEX_ADD_OP,(e))
int
wt_dn2id(
Operation *op,
- WT_SESSION *session,
+ wt_ctx *wc,
struct berval *ndn,
ID *id);
int
wt_dn2id_add(
Operation *op,
- WT_SESSION *session,
+ wt_ctx *wc,
ID pid,
Entry *e);
+int
+wt_dn2idl(
+ Operation *op,
+ wt_ctx *wc,
+ struct berval *ndn,
+ Entry *e,
+ ID *ids,
+ ID *stack);
+
int
wt_dn2id_delete(
Operation *op,
- WT_SESSION *session,
+ wt_ctx *wc,
struct berval *ndn);
+int
+wt_dn2id_has_children(
+ Operation *op,
+ wt_ctx *wc,
+ ID id );
+
/*
* dn2entry.c
*/
wt_ctx *wc,
struct berval *ndn,
Entry **ep );
+int wt_dn2aentry( BackendDB *be,
+ wt_ctx *wc,
+ struct berval *ndn,
+ Entry **ep );
/*
* former ctx.c
wt_ctx *wt_ctx_init(struct wt_info *wi);
void wt_ctx_free(void *key, void *data);
wt_ctx *wt_ctx_get(Operation *op, struct wt_info *wi);
-WT_CURSOR *wt_ctx_index_cursor(wt_ctx *wc, struct berval *name, int create);
+/*
+ * former cache.c
+ */
+int wt_idlcache_get(wt_ctx *wc, struct berval *ndn, int scope, ID *ids);
+int wt_idlcache_set(wt_ctx *wc, struct berval *ndn, int scope, ID *ids);
+int wt_idlcache_begin(wt_ctx *wc, struct berval *ndn, int scope);
+int wt_idlcache_clear(Operation *op, wt_ctx *wc, struct berval *ndn);
/*
* former external.h
extern BI_op_bind wt_bind;
extern BI_op_compare wt_compare;
extern BI_op_delete wt_delete;
-extern BI_op_delete wt_modify;
-
+extern BI_op_modify wt_modify;
+extern BI_op_modrdn wt_modrdn;
extern BI_op_search wt_search;
+extern BI_op_extended wt_extended;
extern BI_operational wt_operational;
+extern BI_has_subordinates wt_hasSubordinates;
/* tools.c */
+int wt_entry_header(WT_ITEM *item, EntryHeader *eh);
extern BI_tool_entry_open wt_tool_entry_open;
extern BI_tool_entry_close wt_tool_entry_close;
extern BI_tool_entry_first_x wt_tool_entry_first_x;
extern BI_tool_entry_reindex wt_tool_entry_reindex;
extern BI_tool_dn2id_get wt_tool_dn2id_get;
extern BI_tool_entry_modify wt_tool_entry_modify;
+extern BI_tool_entry_delete wt_tool_entry_delete;
LDAP_END_DECL
ID *ids )
{
Debug(LDAP_DEBUG_ARGS,
- LDAP_XSTRING(base_candidate)
- ": base: \"%s\" (0x%08lx)\n",
+ "base_candidate: base: \"%s\" (0x%08lx)\n",
e->e_nname.bv_val, (long) e->e_id );
ids[0] = 1;
AttributeAssertion aa_subentry = ATTRIBUTEASSERTION_INIT;
Debug(LDAP_DEBUG_TRACE,
- LDAP_XSTRING(wt_search_candidates)
- ": base=\"%s\" (0x%08lx) scope=%d\n",
+ "wt_search_candidates: base=\"%s\" (0x%08lx) scope=%d\n",
e->e_nname.bv_val, (long) e->e_id, op->oq_search.rs_scope );
xf.f_or = op->oq_search.rs_filter;
if( op->ors_deref & LDAP_DEREF_SEARCHING ) {
rc = search_aliases( op, rs, e, wc->session, ids, scopes, stack );
if ( WT_IDL_IS_ZERO( ids ) && rc == LDAP_SUCCESS )
- rc = wt_dn2idl( op, wc->session, &e->e_nname, e, ids, stack );
+ rc = wt_dn2idl( op, wc, &e->e_nname, e, ids, stack );
} else {
- rc = wt_dn2idl(op, wc->session, &e->e_nname, e, ids, stack );
+ rc = wt_dn2idl(op, wc, &e->e_nname, e, ids, stack );
}
if ( rc == LDAP_SUCCESS ) {
if( rc ) {
Debug(LDAP_DEBUG_TRACE,
- LDAP_XSTRING(wt_search_candidates)
- ": failed (rc=%d)\n",
- rc );
+ "wt_search_candidates: failed (rc=%d)\n", rc );
} else {
Debug(LDAP_DEBUG_TRACE,
- LDAP_XSTRING(wt_search_candidates)
- ": id=%ld first=%ld last=%ld\n",
+ "wt_search_candidates: id=%ld first=%ld last=%ld\n",
(long) ids[0],
(long) WT_IDL_FIRST(ids),
(long) WT_IDL_LAST(ids));
goto done;
}
- AC_MEMCPY( &reqcookie, ps->ps_cookieval.bv_val, sizeof( reqcookie ));
+ memcpy( &reqcookie, ps->ps_cookieval.bv_val, sizeof( reqcookie ));
if ( reqcookie > ps->ps_cookie ) {
/* bad cookie */
struct berval cookie;
Debug(LDAP_DEBUG_ARGS,
- LDAP_XSTRING(send_paged_response)
- ": lastid=0x%08lx nentries=%d\n",
+ "send_paged_response: lastid=0x%08lx nentries=%d\n",
lastid ? *lastid : 0, rs->sr_nentries );
ctrls[1] = NULL;
struct wt_info *wi = (struct wt_info *) op->o_bd->be_private;
ID id, cursor;
ID lastid = NOID;
- AttributeName *attrs;
- OpExtra *oex;
int manageDSAit;
wt_ctx *wc;
- int rc;
+ int rc = LDAP_OTHER;
Entry *e = NULL;
+ Entry *ae = NULL;
Entry *base = NULL;
slap_mask_t mask;
time_t stoptime;
ID candidates[WT_IDL_UM_SIZE];
- ID iscopes[WT_IDL_DB_SIZE];
ID scopes[WT_IDL_DB_SIZE];
int tentries = 0;
unsigned nentries = 0;
- Debug( LDAP_DEBUG_ARGS, "==> " LDAP_XSTRING(wt_search) ": %s\n",
- op->o_req_dn.bv_val );
- attrs = op->oq_search.rs_attrs;
+ Debug( LDAP_DEBUG_ARGS, "==> wt_search: %s\n", op->o_req_dn.bv_val );
manageDSAit = get_manageDSAit( op );
wc = wt_ctx_get(op, wi);
if( !wc ){
Debug( LDAP_DEBUG_ANY,
- LDAP_XSTRING(wt_search)
- ": wt_ctx_get failed: %d\n",
- rc );
+ "wt_search: wt_ctx_get failed: %d\n", rc );
send_ldap_error( op, rs, LDAP_OTHER, "internal error" );
return rc;
}
case 0:
break;
case WT_NOTFOUND:
- Debug( LDAP_DEBUG_ARGS,
- "<== " LDAP_XSTRING(wt_search)
- ": no such object %s\n",
- op->o_req_dn.bv_val );
- rs->sr_err = LDAP_REFERRAL;
- rs->sr_flags = REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED;
- send_ldap_result( op, rs );
- goto done;
+ rc = wt_dn2aentry(op->o_bd, wc, &op->o_req_ndn, &ae);
+ break;
default:
/* TODO: error handling */
Debug( LDAP_DEBUG_ANY,
- LDAP_XSTRING(wt_delete)
- ": error at wt_dn2entry() rc=%d\n",
- rc );
+ "<== wt_search: error at wt_dn2entry() rc=%d\n", rc );
send_ldap_error( op, rs, LDAP_OTHER, "internal error" );
goto done;
}
}
if ( e == NULL ) {
- // TODO
+ if ( ae ) {
+ struct berval matched_dn = BER_BVNULL;
+ /* found ancestor entry */
+ if ( access_allowed( op, ae,
+ slap_schema.si_ad_entry,
+ NULL, ACL_DISCLOSE, NULL ) ) {
+ BerVarray erefs = NULL;
+ ber_dupbv( &matched_dn, &ae->e_name );
+ erefs = is_entry_referral( ae )
+ ? get_entry_referrals( op, ae )
+ : NULL;
+ rs->sr_err = LDAP_REFERRAL;
+ rs->sr_matched = matched_dn.bv_val;
+ if ( erefs ) {
+ rs->sr_ref = referral_rewrite( erefs, &matched_dn,
+ &op->o_req_dn, op->oq_search.rs_scope );
+ ber_bvarray_free( erefs );
+ }
+ Debug( LDAP_DEBUG_ARGS,
+ "wt_search: ancestor is referral\n");
+ rs->sr_flags = REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED;
+ send_ldap_result( op, rs );
+ goto done;
+ }
+ }
+ Debug( LDAP_DEBUG_ARGS,
+ "wt_search: no such object %s\n",
+ op->o_req_dn.bv_val);
+ rs->sr_err = LDAP_NO_SUCH_OBJECT;
+ send_ldap_result( op, rs );
+ goto done;
}
/* NOTE: __NEW__ "search" access is required
}
if ( !manageDSAit && is_entry_referral( e ) ) {
- /* entry is a referral */
- /* TODO: */
+ struct berval matched_dn = BER_BVNULL;
+ BerVarray erefs = NULL;
+ ber_dupbv( &matched_dn, &e->e_name );
+ erefs = get_entry_referrals( op, e );
+ rs->sr_err = LDAP_REFERRAL;
+ if ( erefs ) {
+ rs->sr_ref = referral_rewrite( erefs, &matched_dn,
+ &op->o_req_dn, op->oq_search.rs_scope );
+ ber_bvarray_free( erefs );
+ if ( !rs->sr_ref ) {
+ rs->sr_text = "bad_referral object";
+ }
+ }
+ Debug( LDAP_DEBUG_ARGS, "wt_search: entry is referral\n");
+ rs->sr_matched = matched_dn.bv_val;
+ send_ldap_result( op, rs );
+ ber_bvarray_free( rs->sr_ref );
+ rs->sr_ref = NULL;
+ ber_memfree( matched_dn.bv_val );
+ rs->sr_matched = NULL;
+ goto done;
}
if ( get_assert( op ) &&
case WT_NOTFOUND:
break;
default:
- Debug( LDAP_DEBUG_ANY,
- LDAP_XSTRING(wt_search) ": error search_candidates\n" );
+ Debug( LDAP_DEBUG_ANY, "wt_search: error search_candidates\n" );
send_ldap_error( op, rs, LDAP_OTHER, "internal error" );
goto done;
}
cursor = 0;
if ( candidates[0] == 0 ) {
- Debug( LDAP_DEBUG_TRACE,
- LDAP_XSTRING(wt_search) ": no candidates\n" );
+ Debug( LDAP_DEBUG_TRACE, "wt_search: no candidates\n" );
goto nochange;
}
}
id = wt_idl_first( candidates, &cursor );
if ( id == NOID ) {
- Debug( LDAP_DEBUG_TRACE,
- LDAP_XSTRING(wt_search)
- ": no paged results candidates\n" );
+ Debug( LDAP_DEBUG_TRACE, "wt_search: no paged results candidates\n" );
send_paged_response( op, rs, &lastid, 0 );
rs->sr_err = LDAP_OTHER;
fetch_entry_retry:
- rc = wt_id2entry(op->o_bd, wc->session, id, &e);
+ rc = wt_id2entry(op->o_bd, wc, id, &e);
/* TODO: error handling */
if ( e == NULL ) {
/* TODO: */
case LDAP_SCOPE_ONELEVEL:
scopeok = 1;
break;
+ case LDAP_SCOPE_CHILDREN:
+ if ( id == base->e_id ) break;
+ /* Fall-thru */
case LDAP_SCOPE_SUBTREE:
- scopeok = 1;
+ scopeok = dnIsSuffix(&e->e_nname, &base->e_nname);
break;
}
/* Not in scope, ignore it */
if ( !scopeok )
{
- Debug( LDAP_DEBUG_TRACE,
- LDAP_XSTRING(wt_search)
- ": %ld scope not okay\n",
+ Debug( LDAP_DEBUG_TRACE, "wt_search: %ld scope not okay\n",
(long) id );
goto loop_continue;
}
if ( !manageDSAit && op->oq_search.rs_scope != LDAP_SCOPE_BASE
&& is_entry_referral( e ) )
{
- /* TODO: referral */
+ BerVarray erefs = get_entry_referrals( op, e );
+ rs->sr_ref = referral_rewrite( erefs, &e->e_name, NULL,
+ op->oq_search.rs_scope == LDAP_SCOPE_ONELEVEL
+ ? LDAP_SCOPE_BASE : LDAP_SCOPE_SUBTREE );
+ rs->sr_entry = e;
+ send_search_reference( op, rs );
+ rs->sr_entry = NULL;
+ ber_bvarray_free( rs->sr_ref );
+ ber_bvarray_free( erefs );
+ goto loop_continue;
}
if ( !manageDSAit && is_entry_glue( e )) {
if ( rs->sr_err == LDAP_COMPARE_TRUE ) {
/* check size limit */
if ( get_pagedresults(op) > SLAP_CONTROL_IGNORED ) {
- /* TODO: */
+ if ( rs->sr_nentries >= ((PagedResultsState *)op->o_pagedresults_state)->ps_size ) {
+ wt_entry_return( e );
+ e = NULL;
+ send_paged_response( op, rs, &lastid, tentries );
+ goto done;
+ }
+ lastid = id;
}
if (e) {
rs->sr_attrs = NULL;
rs->sr_entry = NULL;
e = NULL;
- }
- switch ( rs->sr_err ) {
- case LDAP_SUCCESS: /* entry sent ok */
- break;
- default:
- /* TODO: error handling */
- break;
+
+ switch ( rs->sr_err ) {
+ case LDAP_SUCCESS: /* entry sent ok */
+ break;
+ default: /* entry not sent */
+ break;
+ case LDAP_BUSY:
+ send_ldap_result( op, rs );
+ goto done;
+ case LDAP_UNAVAILABLE:
+ rs->sr_err = LDAP_OTHER;
+ goto done;
+ case LDAP_SIZELIMIT_EXCEEDED:
+ rs->sr_ref = rs->sr_v2ref;
+ send_ldap_result( op, rs );
+ rs->sr_err = LDAP_SUCCESS;
+ goto done;
+ }
}
} else {
Debug( LDAP_DEBUG_TRACE,
- LDAP_XSTRING(wt_search)
- ": %ld does not match filter\n",
- (long) id );
+ "wt_search: %ld does not match filter\n", (long) id );
}
loop_continue:
rs->sr_err = (rs->sr_v2ref == NULL) ? LDAP_SUCCESS : LDAP_REFERRAL;
rs->sr_rspoid = NULL;
if ( get_pagedresults(op) > SLAP_CONTROL_IGNORED ) {
- /* not implement yet */
- /* send_paged_response( op, rs, NULL, 0 ); */
+ send_paged_response( op, rs, NULL, 0 );
} else {
send_ldap_result( op, rs );
}
wt_entry_return( e );
}
+ if( ae ) {
+ wt_entry_return( ae );
+ }
+
return rs->sr_err;
}
#define HOLE_SIZE 4096
static dn_id hbuf[HOLE_SIZE], *holes = hbuf;
-static unsigned nhmax = HOLE_SIZE;
static unsigned nholes;
-static int index_nattrs;
-
static struct berval *tool_base;
static int tool_scope;
static Filter *tool_filter;
-static Entry *tool_next_entry;
static wt_ctx *wc;
static WT_CURSOR *reader;
wt_tool_entry_open( BackendDB *be, int mode )
{
struct wt_info *wi = (struct wt_info *) be->be_private;
- WT_CONNECTION *conn = wi->wi_conn;
int rc;
wc = wt_ctx_init(wi);
if( !wc ){
Debug( LDAP_DEBUG_ANY,
- LDAP_XSTRING(wt_tool_entry_open)
- ": wt_ctx_get failed\n" );
+ "wt_tool_entry_open: wt_ctx_get failed\n" );
return -1;
}
,NULL, NULL, &reader);
if ( rc ) {
Debug( LDAP_DEBUG_ANY,
- LDAP_XSTRING(wt_tool_entry_open)
- ": cursor open failed: %s (%d)\n",
+ "wt_tool_entry_open: cursor open failed: %s (%d)\n",
wiredtiger_strerror(rc), rc );
return -1;
}
int
wt_tool_entry_close( BackendDB *be )
{
- int rc;
-
if( reader ) {
reader->close(reader);
reader = NULL;
return NOID;
default:
Debug( LDAP_DEBUG_ANY,
- LDAP_XSTRING(wt_tool_entry_next)
- ": next failed: %s (%d)\n",
+ "wt_tool_entry_next: next failed: %s (%d)\n",
wiredtiger_strerror(rc), rc );
return NOID;
}
rc = reader->get_key(reader, &id);
if( rc ){
Debug( LDAP_DEBUG_ANY,
- LDAP_XSTRING(wt_tool_entry_next)
- ": get_key failed: %s (%d)\n",
- wiredtiger_strerror(rc), rc );
- }
-
- rc = reader->get_value(reader, &item);
- if( rc ){
- Debug( LDAP_DEBUG_ANY,
- LDAP_XSTRING(wt_tool_entry_next)
- ": get_value failed: %s (%d)\n",
+ "wt_tool_entry_next: get_key failed: %s (%d)\n",
wiredtiger_strerror(rc), rc );
}
return id;
return len;
}
-int wt_entry_header(WT_ITEM *item, EntryHeader *eh){
+int wt_entry_header(WT_ITEM *item, EntryHeader *eh)
+{
unsigned char *ptr = (unsigned char *)item->data;
/* Some overlays can create empty entries
assert( be != NULL );
assert( slapMode & SLAP_TOOL_MODE );
+ reader->set_key(reader, id);
+ rc = reader->search(reader);
+ if ( rc ) {
+ Debug( LDAP_DEBUG_ANY,
+ "wt_tool_entry_get: search failed: %s (%d)\n",
+ wiredtiger_strerror(rc), rc );
+ goto done;
+ }
+ rc = reader->get_value(reader, &item);
+ if( rc ){
+ Debug( LDAP_DEBUG_ANY,
+ "wt_tool_entry_get: get_value failed: %s (%d)\n",
+ wiredtiger_strerror(rc), rc );
+ goto done;
+ }
+
rc = wt_entry_header( &item, &eh );
assert( rc == 0 );
eoff = eh.data - (char *)item.data;
e->e_id = id;
}
+done:
return e;
}
struct berval *text,
int hole )
{
- struct wt_info *wi = (struct wt_info *) op->o_bd->be_private;
struct berval dn = e->e_name;
struct berval ndn = e->e_nname;
struct berval pdn, npdn;
return 0;
}
- rc = wt_dn2id(op, wc->session, &ndn, &id);
+ rc = wt_dn2id(op, wc, &ndn, &id);
if(rc == 0){
e->e_id = id;
}else if( rc == WT_NOTFOUND ){
pid = id;
}
wt_next_id( op->o_bd, &e->e_id );
- rc = wt_dn2id_add(op, wc->session, pid, e);
+ rc = wt_dn2id_add(op, wc, pid, e);
if( rc ){
snprintf( text->bv_val, text->bv_len,
"wt_dn2id_add failed: %s (%d)",
ID
wt_tool_entry_put( BackendDB *be, Entry *e, struct berval *text )
{
- struct wt_info *wi = (struct wt_info *) be->be_private;
int rc;
-
- Operation op = {0};
- Opheader ohdr = {0};
+ Operation op = {0};
+ Opheader ohdr = {0};
assert( slapMode & SLAP_TOOL_MODE );
assert( text != NULL );
assert( text->bv_val[0] == '\0' ); /* overconservative? */
Debug( LDAP_DEBUG_TRACE,
- "=> " LDAP_XSTRING(wt_tool_entry_put)
- ": ( \"%s\" )\n", e->e_dn );
+ "=> wt_tool_entry_put: ( \"%s\" )\n", e->e_dn );
rc = wc->session->begin_transaction(wc->session, NULL);
if( rc ){
Debug( LDAP_DEBUG_ANY,
- LDAP_XSTRING(wt_dn2id_add)
- ": begin_transaction failed: %s (%d)\n",
+ "wt_dn2id_add: begin_transaction failed: %s (%d)\n",
wiredtiger_strerror(rc), rc );
return NOID;
}
"wt_tool_next_id failed: %s (%d)",
wiredtiger_strerror(rc), rc );
Debug( LDAP_DEBUG_ANY,
- "=> " LDAP_XSTRING(wt_tool_entry_put) ": %s\n",
- text->bv_val );
+ "=> wt_tool_entry_put: %s\n", text->bv_val );
goto done;
}
- rc = wt_id2entry_add( &op, wc->session, e );
+ rc = wt_id2entry_add( &op, wc, e );
if( rc != 0 ) {
snprintf( text->bv_val, text->bv_len,
"id2entry_add failed: %s (%d)",
wiredtiger_strerror(rc), rc );
Debug( LDAP_DEBUG_ANY,
- "=> " LDAP_XSTRING(wt_tool_entry_put) ": %s\n",
+ "=> wt_tool_entry_put: %s\n",
text->bv_val );
goto done;
}
rc == LDAP_OTHER ? "Internal error" :
wiredtiger_strerror(rc), rc );
Debug( LDAP_DEBUG_ANY,
- "=> " LDAP_XSTRING(wt_tool_entry_put) ": %s\n",
- text->bv_val );
+ "=> wt_tool_entry_put: %s\n", text->bv_val );
goto done;
}
"txn_commit failed: %s (%d)",
wiredtiger_strerror(rc), rc );
Debug( LDAP_DEBUG_ANY,
- "=> " LDAP_XSTRING(wt_tool_entry_put) ": %s\n",
- text->bv_val );
+ "=> wt_tool_entry_put: %s\n", text->bv_val );
e->e_id = NOID;
}
}else{
rc == LDAP_OTHER ? "Internal error" :
wiredtiger_strerror(rc), rc );
Debug( LDAP_DEBUG_ANY,
- "=> " LDAP_XSTRING(wt_tool_entry_put) ": %s\n",
- text->bv_val );
+ "=> wt_tool_entry_put: %s\n", text->bv_val );
e->e_id = NOID;
}
Opheader ohdr = {0};
Debug( LDAP_DEBUG_ARGS,
- "=> " LDAP_XSTRING(wt_tool_entry_reindex) "( %ld )\n",
- (long) id );
+ "=> wt_tool_entry_reindex( %ld )\n", (long) id );
assert( tool_base == NULL );
assert( tool_filter == NULL );
}
if ( j == wi->wi_nattrs ) {
Debug( LDAP_DEBUG_ANY,
- LDAP_XSTRING(wt_tool_entry_reindex)
- ": no index configured for %s\n",
+ "wt_tool_entry_reindex: no index configured for %s\n",
adv[i]->ad_cname.bv_val );
return -1;
}
e = wt_tool_entry_get( be, id );
if( e == NULL ) {
- Debug( LDAP_DEBUG_ANY,
- LDAP_XSTRING(wt_tool_entry_reindex)
+ Debug( LDAP_DEBUG_ANY, "=> wt_tool_entry_reindex"
": could not locate id=%ld\n",
(long) id );
return -1;
rc = wc->session->begin_transaction(wc->session, NULL);
if( rc ){
Debug( LDAP_DEBUG_ANY,
- LDAP_XSTRING(wt_dn2id_add)
- ": begin_transaction failed: %s (%d)\n",
+ "wt_tool_entry_reindex: begin_transaction failed %s (%d)\n",
wiredtiger_strerror(rc), rc );
goto done;
}
Debug( LDAP_DEBUG_TRACE,
- "=> " LDAP_XSTRING(wt_tool_entry_reindex) "( %ld, \"%s\" )\n",
+ "=> wt_tool_entry_reindex( %ld, \"%s\" )\n",
(long) id, e->e_dn );
rc = wt_tool_index_add( &op, wc, e );
rc = wc->session->commit_transaction(wc->session, NULL);
if( rc ) {
Debug( LDAP_DEBUG_ANY,
- "=> " LDAP_XSTRING(wt_tool_entry_reindex)
- "commit_transaction failed: %s (%d)\n",
+ "=> wt_tool_entry_reindex: commit_transaction failed %s (%d)\n",
wiredtiger_strerror(rc), rc );
}
}else{
rc = wc->session->rollback_transaction(wc->session, NULL);
Debug( LDAP_DEBUG_ANY,
- "=> " LDAP_XSTRING(wt_tool_entry_reindex)
- ": rollback transaction %s (%d)\n",
+ "=> wt_tool_entry_reindex: rollback transaction %s (%d)\n",
wiredtiger_strerror(rc), rc );
}
return rc;
}
+ID wt_tool_dn2id_get(
+ Backend *be,
+ struct berval *dn
+)
+{
+ Operation op = {0};
+ Opheader ohdr = {0};
+ ID id;
+ int rc;
+
+ if ( BER_BVISEMPTY(dn) )
+ return 0;
+
+ op.o_hdr = &ohdr;
+ op.o_bd = be;
+ op.o_tmpmemctx = NULL;
+ op.o_tmpmfuncs = &ch_mfuncs;
+
+ rc = wt_dn2id(&op, wc, dn, &id);
+ switch( rc ){
+ case 0:
+ break;
+ case WT_NOTFOUND:
+ return NOID;
+ default:
+ Debug( LDAP_DEBUG_ANY,
+ "wt_tool_entry_get: entry get failed: %s (%d)\n",
+ wiredtiger_strerror(rc), rc );
+ return NOID;
+ }
+ return id;
+}
+
+ID wt_tool_entry_modify(
+ BackendDB *be,
+ Entry *e,
+ struct berval *text )
+{
+ int rc;
+ Operation op = {0};
+ Opheader ohdr = {0};
+
+ assert( be != NULL );
+ assert( slapMode & SLAP_TOOL_MODE );
+
+ assert( text != NULL );
+ assert( text->bv_val != NULL );
+ assert( text->bv_val[0] == '\0' ); /* overconservative? */
+
+ assert ( e->e_id != NOID );
+
+ Debug( LDAP_DEBUG_TRACE,
+ "=> wt_tool_entry_modify( %ld, \"%s\" )\n",
+ (long) e->e_id, e->e_dn );
+
+ rc = wc->session->begin_transaction(wc->session, NULL);
+ if( rc ){
+ Debug( LDAP_DEBUG_ANY, "=> wt_tool_entry_modify"
+ ": begin_transaction failed: %s (%d)\n",
+ wiredtiger_strerror(rc), rc );
+ return NOID;
+ }
+
+ op.o_hdr = &ohdr;
+ op.o_bd = be;
+ op.o_tmpmemctx = NULL;
+ op.o_tmpmfuncs = &ch_mfuncs;
+
+ rc = wt_id2entry_update( &op, wc, e );
+ if( rc != 0 ) {
+ snprintf( text->bv_val, text->bv_len,
+ "id2entry_update failed: %s (%d)",
+ wiredtiger_strerror(rc), rc );
+ Debug( LDAP_DEBUG_ANY, "=> wt_tool_entry_modify: %s\n",
+ text->bv_val );
+ goto done;
+ }
+
+done:
+ if ( rc == 0 ){
+ rc = wc->session->commit_transaction(wc->session, NULL);
+ if( rc != 0 ) {
+ snprintf( text->bv_val, text->bv_len,
+ "txn_commit failed: %s (%d)",
+ wiredtiger_strerror(rc), rc );
+ Debug( LDAP_DEBUG_ANY, "=> wt_tool_entry_modify: %s\n",
+ text->bv_val );
+ e->e_id = NOID;
+ }
+ }else{
+ rc = wc->session->rollback_transaction(wc->session, NULL);
+ snprintf( text->bv_val, text->bv_len,
+ "txn_aborted! %s (%d)",
+ rc == LDAP_OTHER ? "Internal error" :
+ wiredtiger_strerror(rc), rc );
+ Debug( LDAP_DEBUG_ANY, "=> wt_tool_entry_modify: %s\n",
+ text->bv_val );
+ e->e_id = NOID;
+ }
+
+ return e->e_id;
+}
+
+int wt_tool_entry_delete(
+ BackendDB *be,
+ struct berval *ndn,
+ struct berval *text )
+{
+ struct wt_info *wi = (struct wt_info *) be->be_private;
+ int rc;
+ Operation op = {0};
+ Opheader ohdr = {0};
+ Entry *e = NULL;
+
+ assert( be != NULL );
+ assert( slapMode & SLAP_TOOL_MODE );
+
+ assert( text != NULL );
+ assert( text->bv_val != NULL );
+ assert( text->bv_val[0] == '\0' ); /* overconservative? */
+
+ assert ( ndn != NULL );
+ assert ( ndn->bv_val != NULL );
+
+ Debug( LDAP_DEBUG_TRACE,
+ "=> wt_tool_entry_delete( %s )\n",
+ ndn->bv_val );
+
+ op.o_hdr = &ohdr;
+ op.o_bd = be;
+ op.o_tmpmemctx = NULL;
+ op.o_tmpmfuncs = &ch_mfuncs;
+
+ /* get entry */
+ rc = wt_dn2entry(op.o_bd, wc, ndn, &e);
+ switch( rc ) {
+ case 0:
+ break;
+ case WT_NOTFOUND:
+ Debug( LDAP_DEBUG_ARGS,
+ "<== wt_tool_entry_delete: no such object %s\n",
+ ndn->bv_val);
+ goto done;
+ default:
+ Debug( LDAP_DEBUG_ANY,
+ "wt_tool_entry_delete: error at wt_dn2entry() rc=%d\n",
+ rc );
+ goto done;
+ }
+
+ rc = wt_dn2id_has_children( &op, wc, e->e_id );
+ if( rc != WT_NOTFOUND ) {
+ /* subordinate objects must be deleted first */
+ rc = -1;
+ goto done;
+ }
+
+ rc = wc->session->begin_transaction(wc->session, NULL);
+ if( rc ){
+ Debug( LDAP_DEBUG_ANY,
+ "wt_tool_entry_delete: begin_transaction failed: %s (%d)\n",
+ wiredtiger_strerror(rc), rc );
+ goto done;
+ }
+
+ /* delete from dn2id */
+ rc = wt_dn2id_delete( &op, wc, &e->e_nname);
+ if ( rc ) {
+ Debug( LDAP_DEBUG_TRACE,
+ "<== wt_tool_entry_delete: dn2id failed: %s (%d)\n",
+ wiredtiger_strerror(rc), rc );
+ wc->session->rollback_transaction(wc->session, NULL);
+ goto done;
+ }
+
+ /* delete indices for old attributes */
+ rc = wt_index_entry_del( &op, wc, e );
+ if ( rc ) {
+ Debug( LDAP_DEBUG_TRACE,
+ "<== wt_tool_entry_delete: index delete failed: %s (%d)\n",
+ wiredtiger_strerror(rc), rc );
+ wc->session->rollback_transaction(wc->session, NULL);
+ goto done;
+ }
+
+ /* delete from id2entry */
+ rc = wt_id2entry_delete( &op, wc, e );
+ if ( rc ) {
+ Debug( LDAP_DEBUG_TRACE,
+ "<== wt_tool_entry_delete: id2entry failed: %s (%d)\n",
+ wiredtiger_strerror(rc), rc );
+ wc->session->rollback_transaction(wc->session, NULL);
+ goto done;
+ }
+
+ rc = wc->session->commit_transaction(wc->session, NULL);
+ if( rc != 0 ) {
+ snprintf( text->bv_val, text->bv_len,
+ "txn_commit failed: %s (%d)",
+ wiredtiger_strerror(rc), rc );
+ Debug( LDAP_DEBUG_ANY,
+ "=> wt_tool_entry_delete: %s\n",
+ text->bv_val );
+ goto done;
+ }
+
+done:
+ /* free entry */
+ if( e != NULL ) {
+ wt_entry_return( e );
+ }
+ return rc;
+}
+
+
/*
* Local variables:
* indent-tabs-mode: t
BUILD_SQL=@BUILD_SQL@
BUILD_SLAPD=@BUILD_SLAPD@
BUILD_BALANCER=@BUILD_BALANCER@
+BUILD_WT=@BUILD_WT@
# test primary backends (default)
test tests:
@$(MAKE) mdb
@$(MAKE) lloadd
+ @$(MAKE) wt
# test all backends
alltests: tests
@$(MAKE) sql
@$(MAKE) ldif
+ @$(MAKE) wt
mdb test-mdb: mdb-$(BUILD_MDB)
mdb-no:
@echo "Initiating LDAP tests for LDIF..."
@$(RUN) -b ldif all
+wt test-wt: wt-$(BUILD_WT)
+wt-no:
+ @echo "run configure with --enable-wt to run back-wt tests"
+
+wt-yes wt-mod: FORCE
+ @$(RUN) -b wt all
+
lloadd test-lloadd: lloadd-$(BUILD_BALANCER)
lloadd-no:
@echo "run configure with --enable-balancer to run the Load Balancer tests"
To run SQL tests, define SLAPD_USE_SQL=<rdbms> and type
"make sql"; define SLAPD_USE_SQLWRITE=yes
to enable write tests as well.
+ To run WT tests, type "make wt".
To run regression tests, type "make regressions"
The test scripts depends on a number of tools commonly available on
AC_perl=perl@BUILD_PERL@
AC_relay=relay@BUILD_RELAY@
AC_sql=sql@BUILD_SQL@
+AC_wt=@BUILD_WT@
# overlays
AC_accesslog=accesslog@BUILD_ACCESSLOG@
case $BACKEND in
mdb) INDEXDB=indexdb MAINDB=maindb ;;
ndb) INDEXDB=indexdb ;;
+ wt) INDEXDB=indexdb ;;
esac
export BACKEND BACKENDTYPE INDEXDB MAINDB \
if test $REFINT = refintno; then
echo "Referential Integrity overlay not available, test skipped"
exit 0
-fi
+fi
+
+if test $BACKEND = wt ; then
+ echo "back-wt does not support subtree rename"
+ exit 0
+fi
mkdir -p $TESTDIR $DBDIR1
echo "running defines.sh"
. $SRCDIR/scripts/defines.sh
+if test $BACKEND = wt ; then
+ echo "back-wt does not support subtree rename"
+ exit 0
+fi
+
mkdir -p $TESTDIR $DBDIR1
echo "Starting slapd on TCP/IP port $PORT1..."
if test $MEMBEROF = memberofno; then
echo "Memberof overlay not available, test skipped"
exit 0
-fi
+fi
if test $REFINT = refintno; then
echo "Referential Integrity overlay not available, test skipped"
exit 0
-fi
+fi
+
+if test $BACKEND = wt ; then
+ echo "back-wt does not support subtree rename"
+ exit 0
+fi
mkdir -p $TESTDIR $DBDIR1 $TESTDIR/confdir