openldap/servers/slapd/back-wt/cache.c
HAMANO Tsukasa 2aaaf98315 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
2021-08-07 19:27:43 +00:00

231 lines
5.3 KiB
C

/* 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:
*/