Commit 2aaaf983 authored by HAMANO Tsukasa's avatar HAMANO Tsukasa Committed by Quanah Gibson-Mount
Browse files

ITS#9463 cumulative fix for back-wt

- LDAP MODRDN handling
- support paged response
- add wt_extended
- add config emit
- wt_key_read() return WT_NOTFOUND if not found key.
- add ext_candidates()
- fix idlcache session name
- fix warning
- don't reuse idlcache cursor
- set correct pid when modrdn with newsuperior
- fix condition bug
- fix send_search_entry() error handling
- fix for referral handling
- fix for readonly mode
- fix sizelimit response
- support modrdn
- improve modify handling
- clear ancestor idlcache
- fix for multi-DIT
- IMPORTANT CHANGES: Compatibility is broken with previous database table, please restore database from LDIF.
- checking for scope=children
- sort dn2idl result
- fix cursor leak
- support db_open with readonly mode
- add wt_tool_entry_delete
- initialize comp variable
- support referrals
- implement wt_tool_dn2id_get() and wt_tool_entry_modify() for slapadd -w
- skip redundant scan, and more debug message
- fix OID conflict with back-passwd
- no need to close session, It may cause SEGV.
- fixed wt_dn2entry for empty DN
- support multiple database
- Construct wiredtiger's config parameter. It allow multi line wtconfig settings
- add idlcache
- fix concurrent modification to a entry with multi values
- prevent to add duplicate dn entry
- suppress error message "search_near failed: WT_NOTFOUND"
- update Debug statements
- back-wt does not support subtree rename
- fix for @ondra review
- update slapd-wt.5 and warning for mode option
- add back-wt test into test target
- add scope checking
parent f19a1da1
......@@ -33,6 +33,25 @@ A separate directory must be specified for each database.
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).
......@@ -52,19 +71,6 @@ maximum heap memory to allocate for the cache.
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
......
......@@ -14,18 +14,18 @@
## <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
......
......@@ -34,20 +34,17 @@ wt_add( Operation *op, SlapReply *rs )
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;
......@@ -57,8 +54,7 @@ wt_add( Operation *op, SlapReply *rs )
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;
}
......@@ -68,8 +64,7 @@ wt_add( Operation *op, SlapReply *rs )
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;
}
......@@ -97,9 +92,7 @@ wt_add( Operation *op, SlapReply *rs )
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 );
......@@ -117,9 +110,7 @@ wt_add( Operation *op, SlapReply *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;
......@@ -133,9 +124,7 @@ wt_add( Operation *op, SlapReply *rs )
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;
......@@ -156,9 +145,7 @@ wt_add( Operation *op, SlapReply *rs )
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;
......@@ -173,8 +160,7 @@ wt_add( Operation *op, SlapReply *rs )
*/
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;;
......@@ -185,8 +171,7 @@ wt_add( Operation *op, SlapReply *rs )
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;;
......@@ -196,8 +181,7 @@ wt_add( Operation *op, SlapReply *rs )
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;;
......@@ -213,8 +197,7 @@ wt_add( Operation *op, SlapReply *rs )
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;
......@@ -261,8 +244,7 @@ wt_add( Operation *op, SlapReply *rs )
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;
......@@ -272,33 +254,29 @@ wt_add( Operation *op, SlapReply *rs )
* 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:
......@@ -311,11 +289,10 @@ wt_add( Operation *op, SlapReply *rs )
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;
......@@ -332,8 +309,7 @@ wt_add( Operation *op, SlapReply *rs )
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";
......@@ -344,8 +320,7 @@ wt_add( Operation *op, SlapReply *rs )
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";
......@@ -363,9 +338,7 @@ wt_add( Operation *op, SlapReply *rs )
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? */
......@@ -375,12 +348,11 @@ wt_add( Operation *op, SlapReply *rs )
}
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 );
......
......@@ -21,6 +21,7 @@
#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
......@@ -57,7 +58,7 @@ wt_attr_slot( struct wt_info *wi, AttributeDescription *ad, int *ins )
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? */
......@@ -357,6 +358,44 @@ done:
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 )
{
......@@ -377,8 +416,6 @@ wt_attr_index_destroy( struct wt_info *wi )
free( wi->wi_attrs );
}
/*
* Local variables:
* indent-tabs-mode: t
......
......@@ -33,10 +33,13 @@
/* 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;
......@@ -53,23 +56,41 @@ struct wt_info {
#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.) */
......
......@@ -29,15 +29,13 @@ int
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 */
......@@ -59,8 +57,7 @@ wt_bind( Operation *op, SlapReply *rs )
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 );
......
/* 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",