diff options
Diffstat (limited to '')
-rw-r--r-- | servers/slapd/back-wt/id2entry.c | 352 |
1 files changed, 352 insertions, 0 deletions
diff --git a/servers/slapd/back-wt/id2entry.c b/servers/slapd/back-wt/id2entry.c new file mode 100644 index 0000000..95b197c --- /dev/null +++ b/servers/slapd/back-wt/id2entry.c @@ -0,0 +1,352 @@ +/* OpenLDAP WiredTiger backend */ +/* $OpenLDAP$ */ +/* This work is part of OpenLDAP Software <http://www.openldap.org/>. + * + * Copyright 2002-2022 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 "back-wt.h" +#include "slap-config.h" + +static int wt_id2entry_put( + Operation *op, + wt_ctx *wc, + Entry *e, + WT_CURSOR *cursor) +{ + struct berval bv; + WT_ITEM item; + int rc; + + rc = entry_encode( e, &bv ); + if(rc != LDAP_SUCCESS){ + return -1; + } + item.size = bv.bv_len; + item.data = bv.bv_val; + + 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, + "wt_id2entry_put: insert failed: %s (%d)\n", + wiredtiger_strerror(rc), rc ); + goto done; + } + +done: + ch_free( bv.bv_val ); + + return rc; +} + +int wt_id2entry_add( + Operation *op, + wt_ctx *wc, + Entry *e ) +{ + 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_ctx *wc, + Entry *e ) +{ + 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_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, + "wt_id2entry_delete: open_cursor failed: %s (%d)\n", + wiredtiger_strerror(rc), rc ); + goto done; + } + cursor->set_key(cursor, e->e_id); + rc = cursor->remove(cursor); + if ( rc ) { + Debug( LDAP_DEBUG_ANY, + "wt_id2entry_delete: remove failed: %s (%d)\n", + wiredtiger_strerror(rc), rc ); + goto done; + } + +done: + if(cursor){ + cursor->close(cursor); + } + return rc; +} + +int wt_id2entry( BackendDB *be, + wt_ctx *wc, + ID id, + Entry **ep ){ + int rc; + WT_SESSION *session = wc->session; + WT_CURSOR *cursor = wc->id2entry; + WT_ITEM item; + EntryHeader eh; + int eoff; + Entry *e = NULL; + + 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 = cursor->search(cursor); + if ( rc ) { + goto done; + } + + cursor->get_value(cursor, &item); + rc = wt_entry_header( &item, &eh ); + eoff = eh.data - (char *)item.data; + eh.bv.bv_len = eh.nvals * sizeof( struct berval ) + item.size; + eh.bv.bv_val = ch_malloc( eh.bv.bv_len ); + memset(eh.bv.bv_val, 0xff, eh.bv.bv_len); + eh.data = eh.bv.bv_val + eh.nvals * sizeof( struct berval ); + memcpy(eh.data, item.data, item.size); + eh.data += eoff; + rc = entry_decode( &eh, &e ); + if ( rc ) { + Debug( LDAP_DEBUG_ANY, + "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; +} + +int wt_entry_return( + Entry *e + ) +{ + if ( !e ) { + return 0; + } + + /* Our entries are allocated in two blocks; the data comes from + * the db itself and the Entry structure and associated pointers + * are allocated in entry_decode. The db data pointer is saved + * in e_bv. + */ + if ( e->e_bv.bv_val ) { +#if 0 + /* See if the DNs were changed by modrdn */ + if( e->e_nname.bv_val < e->e_bv.bv_val || e->e_nname.bv_val > + e->e_bv.bv_val + e->e_bv.bv_len ) { + ch_free(e->e_name.bv_val); + ch_free(e->e_nname.bv_val); + } +#endif + e->e_name.bv_val = NULL; + e->e_nname.bv_val = NULL; + /* In tool mode the e_bv buffer is realloc'd, leave it alone */ + if( !(slapMode & SLAP_TOOL_MODE) ) { + free( e->e_bv.bv_val ); + } + BER_BVZERO( &e->e_bv ); + } + + entry_free( e ); +} + +int wt_entry_release( + Operation *op, + Entry *e, + int rw ) +{ + return wt_entry_return( e ); +} + +/* + * return LDAP_SUCCESS IFF we can retrieve the specified entry. + */ +int wt_entry_get( + Operation *op, + struct berval *ndn, + ObjectClass *oc, + AttributeDescription *at, + int rw, + Entry **ent ) +{ + 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; +} + +/* + * Local variables: + * indent-tabs-mode: t + * tab-width: 4 + * c-basic-offset: 4 + * End: + */ |