1 /* OpenLDAP WiredTiger backend */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 * Copyright 2002-2015 The OpenLDAP Foundation.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted only as authorized by the OpenLDAP
12 * A copy of this license is available in the file LICENSE in the
13 * top-level directory of the distribution or, alternatively, at
14 * <http://www.OpenLDAP.org/license.html>.
17 * This work was developed by HAMANO Tsukasa <hamano@osstech.co.jp>
18 * based on back-bdb for inclusion in OpenLDAP Software.
19 * WiredTiger is a product of MongoDB Inc.
25 #include <ac/string.h>
29 typedef struct dn_id {
34 #define HOLE_SIZE 4096
35 static dn_id hbuf[HOLE_SIZE], *holes = hbuf;
36 static unsigned nhmax = HOLE_SIZE;
37 static unsigned nholes;
39 static int index_nattrs;
41 static struct berval *tool_base;
42 static int tool_scope;
43 static Filter *tool_filter;
44 static Entry *tool_next_entry;
47 static WT_CURSOR *reader;
51 wt_tool_entry_open( BackendDB *be, int mode )
53 struct wt_info *wi = (struct wt_info *) be->be_private;
54 WT_CONNECTION *conn = wi->wi_conn;
59 Debug( LDAP_DEBUG_ANY,
60 LDAP_XSTRING(wt_tool_entry_open)
61 ": wt_ctx_get failed: %s (%d)\n",
66 rc = wc->session->open_cursor(wc->session, WT_TABLE_ID2ENTRY"(entry)"
67 ,NULL, NULL, &reader);
69 Debug( LDAP_DEBUG_ANY,
70 LDAP_XSTRING(wt_tool_entry_open)
71 ": cursor open failed: %s (%d)\n",
72 wiredtiger_strerror(rc), rc, 0 );
80 wt_tool_entry_close( BackendDB *be )
85 reader->close(reader);
89 wt_ctx_free(NULL, wc);
93 fprintf( stderr, "Error, entries missing!\n");
94 for (i=0; i<nholes; i++) {
95 fprintf(stderr, " entry %ld: %s\n",
96 holes[i].id, holes[i].dn.bv_val);
105 wt_tool_entry_first_x( BackendDB *be,
114 return wt_tool_entry_next( be );
118 wt_tool_entry_next( BackendDB *be )
123 rc = reader->next(reader);
130 Debug( LDAP_DEBUG_ANY,
131 LDAP_XSTRING(wt_tool_entry_next)
132 ": next failed: %s (%d)\n",
133 wiredtiger_strerror(rc), rc, 0 );
137 rc = reader->get_key(reader, &id);
139 Debug( LDAP_DEBUG_ANY,
140 LDAP_XSTRING(wt_tool_entry_next)
141 ": get_key failed: %s (%d)\n",
142 wiredtiger_strerror(rc), rc, 0 );
145 rc = reader->get_value(reader, &item);
147 Debug( LDAP_DEBUG_ANY,
148 LDAP_XSTRING(wt_tool_entry_next)
149 ": get_value failed: %s (%d)\n",
150 wiredtiger_strerror(rc), rc, 0 );
156 entry_getlen(unsigned char **buf)
173 int wt_entry_header(WT_ITEM *item, EntryHeader *eh){
174 unsigned char *ptr = (unsigned char *)item->data;
176 /* Some overlays can create empty entries
177 * so don't check for zeros here.
179 eh->nattrs = entry_getlen(&ptr);
180 eh->nvals = entry_getlen(&ptr);
181 eh->data = (char *)ptr;
186 wt_tool_entry_get( BackendDB *be, ID id )
189 static EntryHeader eh;
192 assert( be != NULL );
193 assert( slapMode & SLAP_TOOL_MODE );
195 rc = wt_entry_header( &item, &eh );
197 eoff = eh.data - (char *)item.data;
199 eh.bv.bv_len = eh.nvals * sizeof( struct berval ) + item.size;
200 eh.bv.bv_val = ch_realloc( eh.bv.bv_val, eh.bv.bv_len );
201 memset(eh.bv.bv_val, 0xff, eh.bv.bv_len);
202 eh.data = eh.bv.bv_val + eh.nvals * sizeof( struct berval );
203 memcpy(eh.data, item.data, item.size);
206 rc = entry_decode( &eh, &e );
209 if( rc == LDAP_SUCCESS ) {
216 static int wt_tool_next_id(
222 struct wt_info *wi = (struct wt_info *) op->o_bd->be_private;
223 struct berval dn = e->e_name;
224 struct berval ndn = e->e_nname;
225 struct berval pdn, npdn;
235 rc = wt_dn2id(op, wc->session, &ndn, &id);
238 }else if( rc == WT_NOTFOUND ){
239 if ( !be_issuffix( op->o_bd, &ndn ) ) {
241 dnParent( &dn, &pdn );
242 dnParent( &ndn, &npdn );
245 rc = wt_tool_next_id( op, e, text, 1 );
251 /* If parent didn't exist, it was created just now
252 * and its ID is now in e->e_id. Make sure the current
253 * entry gets added under the new parent ID.
255 if ( eid != e->e_id ) {
261 wt_next_id( op->o_bd, &e->e_id );
262 rc = wt_dn2id_add(op, wc->session, pid, e);
264 snprintf( text->bv_val, text->bv_len,
265 "wt_dn2id_add failed: %s (%d)",
266 wiredtiger_strerror(rc), rc );
267 Debug( LDAP_DEBUG_ANY,
268 "=> wt_tool_next_id: %s\n", text->bv_val, 0, 0 );
275 for ( i=0; i<nholes; i++) {
276 if ( holes[i].id == e->e_id ) {
277 free(holes[i].dn.bv_val);
278 for (j=i;j<nholes;j++) holes[j] = holes[j+1];
282 } else if ( holes[i].id > e->e_id ) {
296 return wt_index_entry_add( op, wc, e );
300 wt_tool_entry_put( BackendDB *be, Entry *e, struct berval *text )
302 struct wt_info *wi = (struct wt_info *) be->be_private;
308 assert( slapMode & SLAP_TOOL_MODE );
309 assert( text != NULL );
310 assert( text->bv_val != NULL );
311 assert( text->bv_val[0] == '\0' ); /* overconservative? */
313 Debug( LDAP_DEBUG_TRACE,
314 "=> " LDAP_XSTRING(wt_tool_entry_put)
315 ": ( \"%s\" )\n", e->e_dn, 0, 0);
317 rc = wc->session->begin_transaction(wc->session, NULL);
319 Debug( LDAP_DEBUG_ANY,
320 LDAP_XSTRING(wt_dn2id_add)
321 ": begin_transaction failed: %s (%d)\n",
322 wiredtiger_strerror(rc), rc, 0 );
328 op.o_tmpmemctx = NULL;
329 op.o_tmpmfuncs = &ch_mfuncs;
331 rc = wt_tool_next_id( &op, e, text, 0 );
333 snprintf( text->bv_val, text->bv_len,
334 "wt_tool_next_id failed: %s (%d)",
335 wiredtiger_strerror(rc), rc );
336 Debug( LDAP_DEBUG_ANY,
337 "=> " LDAP_XSTRING(wt_tool_entry_put) ": %s\n",
338 text->bv_val, 0, 0 );
342 rc = wt_id2entry_add( &op, wc->session, e );
344 snprintf( text->bv_val, text->bv_len,
345 "id2entry_add failed: %s (%d)",
346 wiredtiger_strerror(rc), rc );
347 Debug( LDAP_DEBUG_ANY,
348 "=> " LDAP_XSTRING(wt_tool_entry_put) ": %s\n",
349 text->bv_val, 0, 0 );
353 rc = wt_tool_index_add( &op, wc, e );
355 snprintf( text->bv_val, text->bv_len,
356 "index_entry_add failed: %s (%d)",
357 rc == LDAP_OTHER ? "Internal error" :
358 wiredtiger_strerror(rc), rc );
359 Debug( LDAP_DEBUG_ANY,
360 "=> " LDAP_XSTRING(wt_tool_entry_put) ": %s\n",
361 text->bv_val, 0, 0 );
367 rc = wc->session->commit_transaction(wc->session, NULL);
369 snprintf( text->bv_val, text->bv_len,
370 "txn_commit failed: %s (%d)",
371 wiredtiger_strerror(rc), rc );
372 Debug( LDAP_DEBUG_ANY,
373 "=> " LDAP_XSTRING(wt_tool_entry_put) ": %s\n",
374 text->bv_val, 0, 0 );
378 rc = wc->session->rollback_transaction(wc->session, NULL);
379 snprintf( text->bv_val, text->bv_len,
380 "txn_aborted! %s (%d)",
381 rc == LDAP_OTHER ? "Internal error" :
382 wiredtiger_strerror(rc), rc );
383 Debug( LDAP_DEBUG_ANY,
384 "=> " LDAP_XSTRING(wt_tool_entry_put) ": %s\n",
385 text->bv_val, 0, 0 );
392 int wt_tool_entry_reindex(
395 AttributeDescription **adv )
397 struct wt_info *wi = (struct wt_info *) be->be_private;
403 Debug( LDAP_DEBUG_ARGS,
404 "=> " LDAP_XSTRING(wt_tool_entry_reindex) "( %ld )\n",
406 assert( tool_base == NULL );
407 assert( tool_filter == NULL );
409 /* No indexes configured, nothing to do. Could return an
410 * error here to shortcut things.
416 /* Check for explicit list of attrs to index */
420 if ( wi->wi_attrs[0]->ai_desc != adv[0] ) {
422 for ( n = 0; adv[n]; n++ ) ;
425 for ( i = 0; i < n; i++ ) {
426 AttributeDescription *ad = adv[i];
427 for ( j = i-1; j>=0; j--) {
428 if ( SLAP_PTRCMP( adv[j], ad ) <= 0 ) break;
435 for ( i = 0; adv[i]; i++ ) {
436 if ( wi->wi_attrs[i]->ai_desc != adv[i] ) {
437 for ( j = i+1; j < wi->wi_nattrs; j++ ) {
438 if ( wi->wi_attrs[j]->ai_desc == adv[i] ) {
439 AttrInfo *ai = wi->wi_attrs[i];
440 wi->wi_attrs[i] = wi->wi_attrs[j];
441 wi->wi_attrs[j] = ai;
445 if ( j == wi->wi_nattrs ) {
446 Debug( LDAP_DEBUG_ANY,
447 LDAP_XSTRING(wt_tool_entry_reindex)
448 ": no index configured for %s\n",
449 adv[i]->ad_cname.bv_val, 0, 0 );
457 e = wt_tool_entry_get( be, id );
460 Debug( LDAP_DEBUG_ANY,
461 LDAP_XSTRING(wt_tool_entry_reindex)
462 ": could not locate id=%ld\n",
469 op.o_tmpmemctx = NULL;
470 op.o_tmpmfuncs = &ch_mfuncs;
472 rc = wc->session->begin_transaction(wc->session, NULL);
474 Debug( LDAP_DEBUG_ANY,
475 LDAP_XSTRING(wt_dn2id_add)
476 ": begin_transaction failed: %s (%d)\n",
477 wiredtiger_strerror(rc), rc, 0 );
480 Debug( LDAP_DEBUG_TRACE,
481 "=> " LDAP_XSTRING(wt_tool_entry_reindex) "( %ld, \"%s\" )\n",
482 (long) id, e->e_dn, 0 );
484 rc = wt_tool_index_add( &op, wc, e );
488 rc = wc->session->commit_transaction(wc->session, NULL);
490 Debug( LDAP_DEBUG_ANY,
491 "=> " LDAP_XSTRING(wt_tool_entry_reindex)
492 "commit_transaction failed: %s (%d)\n",
493 wiredtiger_strerror(rc), rc, 0 );
496 rc = wc->session->rollback_transaction(wc->session, NULL);
497 Debug( LDAP_DEBUG_ANY,
498 "=> " LDAP_XSTRING(wt_tool_entry_reindex)
499 ": rollback transaction %s\n",
500 wiredtiger_strerror(rc), rc, 0 );
503 wt_entry_release( &op, e, 0 );
510 * indent-tabs-mode: t