1 /* tools.c - tools for slap tools */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 * Copyright 2000-2004 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>.
20 #include <ac/string.h>
26 static DBC *cursor = NULL;
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 Avlnode *index_attrs, index_dummy;
41 int bdb_tool_entry_open(
42 BackendDB *be, int mode )
44 /* initialize key and data thangs */
47 key.flags = DB_DBT_REALLOC;
48 data.flags = DB_DBT_REALLOC;
53 int bdb_tool_entry_close(
68 cursor->c_close( cursor );
74 fprintf( stderr, "Error, entries missing!\n");
75 for (i=0; i<nholes; i++) {
76 fprintf(stderr, " entry %ld: %s\n",
77 holes[i].id, holes[i].dn.bv_val);
85 static int bdb_reindex_cmp(const void *a, const void *b) { return 0; }
87 ID bdb_tool_entry_next(
92 struct bdb_info *bdb = (struct bdb_info *) be->be_private;
95 assert( slapMode & SLAP_TOOL_MODE );
96 assert( bdb != NULL );
100 rc = bdb->bi_id2entry->bdi_db->cursor(
101 bdb->bi_id2entry->bdi_db, NULL, &cursor,
102 bdb->bi_db_opflags );
108 rc = cursor->c_get( cursor, &key, &data, DB_NEXT );
111 /* If we're doing linear indexing and there are more attrs to
112 * index, and we're at the end of the database, start over.
114 if ( bdb->bi_attrs == &index_dummy ) {
115 if ( index_attrs && rc == DB_NOTFOUND ) {
116 /* optional - do a checkpoint here? */
117 index_dummy.avl_data = avl_delete(&index_attrs, NULL, bdb_reindex_cmp);
118 rc = cursor->c_get( cursor, &key, &data, DB_FIRST );
121 bdb->bi_attrs = NULL;
129 if( data.data == NULL ) {
133 AC_MEMCPY( &id, key.data, key.size );
137 ID bdb_tool_dn2id_get(
142 struct bdb_info *bdb = (struct bdb_info *) be->be_private;
143 DB *db = bdb->bi_dn2id->bdi_db;
149 key.size = dn->bv_len + 2;
150 key.data = ch_malloc( key.size );
151 ((char*)key.data)[0] = DN_BASE_PREFIX;
152 AC_MEMCPY( &((char*)key.data)[1], dn->bv_val, key.size - 1 );
156 data.ulen = sizeof(ID);
157 data.flags = DB_DBT_USERMEM;
159 rc = db->get( db, NULL, &key, &data, bdb->bi_db_opflags );
163 LDAP_LOG ( INDEX, ERR, "bdb_tool_dn2id_get: get failed %s (%d)\n",
164 db_strerror(rc), rc, 0 );
166 Debug( LDAP_DEBUG_TRACE, "bdb_tool_dn2id_get: get failed: %s (%d)\n",
167 db_strerror( rc ), rc, 0 );
176 int bdb_tool_id2entry_get(
182 return bdb_id2entry( be, NULL, id, e );
185 Entry* bdb_tool_entry_get( BackendDB *be, ID id )
191 assert( be != NULL );
192 assert( slapMode & SLAP_TOOL_MODE );
193 assert( data.data != NULL );
196 DBT2bv( &data, &bv );
198 rc = entry_decode( &bv, &e );
200 if( rc == LDAP_SUCCESS ) {
205 EntryInfo *ei = NULL;
209 op.o_tmpmemctx = NULL;
210 op.o_tmpmfuncs = &ch_mfuncs;
212 rc = bdb_cache_find_id( &op, NULL, id, &ei, 0, 0, NULL );
213 if ( rc == LDAP_SUCCESS )
220 static int bdb_tool_next_id(
227 struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
228 struct berval dn = e->e_name;
229 struct berval ndn = e->e_nname;
230 struct berval pdn, npdn;
231 EntryInfo *ei = NULL;
234 if (ndn.bv_len == 0) return 0;
236 rc = bdb_cache_find_ndn( op, tid, &ndn, &ei );
237 if ( ei ) bdb_cache_entryinfo_unlock( ei );
238 if ( rc == DB_NOTFOUND ) {
239 if ( !be_issuffix( op->o_bd, &ndn ) ) {
240 dnParent( &dn, &pdn );
241 dnParent( &ndn, &npdn );
244 rc = bdb_tool_next_id( op, tid, e, text, 1 );
251 rc = bdb_next_id( op->o_bd, tid, &e->e_id );
253 snprintf( text->bv_val, text->bv_len,
254 "next_id failed: %s (%d)",
255 db_strerror(rc), rc );
257 LDAP_LOG ( TOOLS, ERR,
258 "=> bdb_tool_next_id: %s\n", text->bv_val, 0, 0 );
260 Debug( LDAP_DEBUG_ANY,
261 "=> bdb_tool_next_id: %s\n", text->bv_val, 0, 0 );
265 rc = bdb_dn2id_add( op, tid, ei, e );
267 snprintf( text->bv_val, text->bv_len,
268 "dn2id_add failed: %s (%d)",
269 db_strerror(rc), rc );
271 LDAP_LOG ( TOOLS, ERR,
272 "=> bdb_tool_next_id: %s\n", text->bv_val, 0, 0 );
274 Debug( LDAP_DEBUG_ANY,
275 "=> bdb_tool_next_id: %s\n", text->bv_val, 0, 0 );
278 if ( nholes == nhmax - 1 ) {
279 if ( holes == hbuf ) {
280 holes = ch_malloc( nhmax * sizeof(dn_id) * 2 );
281 AC_MEMCPY( holes, hbuf, sizeof(hbuf) );
283 holes = ch_realloc( holes, nhmax * sizeof(dn_id) * 2 );
287 ber_dupbv( &holes[nholes].dn, &ndn );
288 holes[nholes++].id = e->e_id;
290 } else if ( !hole ) {
293 e->e_id = ei->bei_id;
295 for ( i=0; i<nholes; i++) {
296 if ( holes[i].id == e->e_id ) {
298 free(holes[i].dn.bv_val);
299 for (j=i;j<nholes;j++) holes[j] = holes[j+1];
303 } else if ( holes[i].id > e->e_id ) {
311 ID bdb_tool_entry_put(
314 struct berval *text )
317 struct bdb_info *bdb = (struct bdb_info *) be->be_private;
321 assert( be != NULL );
322 assert( slapMode & SLAP_TOOL_MODE );
325 assert( text->bv_val );
326 assert( text->bv_val[0] == '\0' ); /* overconservative? */
329 LDAP_LOG ( TOOLS, ARGS, "=> bdb_tool_entry_put( %ld, \"%s\" )\n",
330 (long) e->e_id, e->e_dn, 0 );
332 Debug( LDAP_DEBUG_TRACE, "=> bdb_tool_entry_put( %ld, \"%s\" )\n",
333 (long) e->e_id, e->e_dn, 0 );
336 rc = TXN_BEGIN( bdb->bi_dbenv, NULL, &tid,
337 bdb->bi_db_opflags );
339 snprintf( text->bv_val, text->bv_len,
340 "txn_begin failed: %s (%d)",
341 db_strerror(rc), rc );
343 LDAP_LOG ( TOOLS, ERR, "=> bdb_tool_entry_put: %s\n", text->bv_val, 0, 0 );
345 Debug( LDAP_DEBUG_ANY,
346 "=> bdb_tool_entry_put: %s\n",
347 text->bv_val, 0, 0 );
353 op.o_tmpmemctx = NULL;
354 op.o_tmpmfuncs = &ch_mfuncs;
356 /* add dn2id indices */
357 rc = bdb_tool_next_id( &op, tid, e, text, 0 );
363 rc = bdb_id2entry_add( be, tid, e );
365 snprintf( text->bv_val, text->bv_len,
366 "id2entry_add failed: %s (%d)",
367 db_strerror(rc), rc );
369 LDAP_LOG ( TOOLS, ERR,
370 "=> bdb_tool_entry_put: %s\n", text->bv_val, 0, 0 );
372 Debug( LDAP_DEBUG_ANY,
373 "=> bdb_tool_entry_put: %s\n", text->bv_val, 0, 0 );
378 if ( !bdb->bi_linear_index )
379 rc = bdb_index_entry_add( &op, tid, e );
381 snprintf( text->bv_val, text->bv_len,
382 "index_entry_add failed: %s (%d)",
383 db_strerror(rc), rc );
385 LDAP_LOG ( TOOLS, ERR,
386 "=> bdb_tool_entry_put: %s\n", text->bv_val, 0, 0 );
388 Debug( LDAP_DEBUG_ANY,
389 "=> bdb_tool_entry_put: %s\n", text->bv_val, 0, 0 );
396 rc = TXN_COMMIT( tid, 0 );
398 snprintf( text->bv_val, text->bv_len,
399 "txn_commit failed: %s (%d)",
400 db_strerror(rc), rc );
402 LDAP_LOG ( TOOLS, ERR,
403 "=> bdb_tool_entry_put: %s\n", text->bv_val, 0, 0 );
405 Debug( LDAP_DEBUG_ANY,
406 "=> bdb_tool_entry_put: %s\n",
407 text->bv_val, 0, 0 );
414 snprintf( text->bv_val, text->bv_len,
415 "txn_aborted! %s (%d)",
416 db_strerror(rc), rc );
418 LDAP_LOG ( TOOLS, ERR,
419 "=> bdb_tool_entry_put: %s\n", text->bv_val, 0, 0 );
421 Debug( LDAP_DEBUG_ANY,
422 "=> bdb_tool_entry_put: %s\n",
423 text->bv_val, 0, 0 );
431 int bdb_tool_entry_reindex(
435 struct bdb_info *bi = (struct bdb_info *) be->be_private;
442 LDAP_LOG ( TOOLS, ARGS,
443 "=> bdb_tool_entry_reindex( %ld )\n", (long) id, 0, 0 );
445 Debug( LDAP_DEBUG_ARGS, "=> bdb_tool_entry_reindex( %ld )\n",
449 /* No indexes configured, nothing to do. Could return an
450 * error here to shortcut things.
456 /* Get the first attribute to index */
457 if (bi->bi_linear_index && !index_attrs && bi->bi_attrs != &index_dummy) {
458 index_attrs = bi->bi_attrs;
459 bi->bi_attrs = &index_dummy;
460 index_dummy.avl_data = avl_delete(&index_attrs, NULL, bdb_reindex_cmp);
463 e = bdb_tool_entry_get( be, id );
467 LDAP_LOG ( TOOLS, DETAIL1,
468 "bdb_tool_entry_reindex:: could not locate id=%ld\n",
471 Debug( LDAP_DEBUG_ANY,
472 "bdb_tool_entry_reindex:: could not locate id=%ld\n",
478 rc = TXN_BEGIN( bi->bi_dbenv, NULL, &tid, bi->bi_db_opflags );
481 LDAP_LOG ( TOOLS, ERR,
482 "=> bdb_tool_entry_reindex: txn_begin failed: %s (%d)\n",
483 db_strerror(rc), rc, 0 );
485 Debug( LDAP_DEBUG_ANY,
486 "=> bdb_tool_entry_reindex: txn_begin failed: %s (%d)\n",
487 db_strerror(rc), rc, 0 );
493 * just (re)add them for now
494 * assume that some other routine (not yet implemented)
495 * will zap index databases
500 LDAP_LOG ( TOOLS, ERR,
501 "=> bdb_tool_entry_reindex( %ld, \"%s\" )\n", (long) id, e->e_dn, 0 );
503 Debug( LDAP_DEBUG_TRACE, "=> bdb_tool_entry_reindex( %ld, \"%s\" )\n",
504 (long) id, e->e_dn, 0 );
508 op.o_tmpmemctx = NULL;
509 op.o_tmpmfuncs = &ch_mfuncs;
511 #if 0 /* ndef BDB_HIER */
512 /* add dn2id indices */
513 rc = bdb_dn2id_add( &op, tid, NULL, e );
514 if( rc != 0 && rc != DB_KEYEXIST ) {
516 LDAP_LOG ( TOOLS, ERR,
517 "=> bdb_tool_entry_reindex: dn2id_add failed: %s (%d)\n",
518 db_strerror(rc), rc, 0 );
520 Debug( LDAP_DEBUG_ANY,
521 "=> bdb_tool_entry_reindex: dn2id_add failed: %s (%d)\n",
522 db_strerror(rc), rc, 0 );
528 rc = bdb_index_entry_add( &op, tid, e );
532 rc = TXN_COMMIT( tid, 0 );
535 LDAP_LOG ( TOOLS, ERR,
536 "=> bdb_tool_entry_reindex: txn_commit failed: %s (%d)\n",
537 db_strerror(rc), rc, 0 );
539 Debug( LDAP_DEBUG_ANY,
540 "=> bdb_tool_entry_reindex: txn_commit failed: %s (%d)\n",
541 db_strerror(rc), rc, 0 );
549 LDAP_LOG ( TOOLS, DETAIL1,
550 "=> bdb_tool_entry_reindex: txn_aborted! %s (%d)\n",
551 db_strerror(rc), rc, 0 );
553 Debug( LDAP_DEBUG_ANY,
554 "=> bdb_tool_entry_reindex: txn_aborted! %s (%d)\n",
555 db_strerror(rc), rc, 0 );
559 bdb_entry_release( &op, e, 0 );
564 ID bdb_tool_entry_modify(
567 struct berval *text )
570 struct bdb_info *bdb = (struct bdb_info *) be->be_private;
574 assert( be != NULL );
575 assert( slapMode & SLAP_TOOL_MODE );
578 assert( text->bv_val );
579 assert( text->bv_val[0] == '\0' ); /* overconservative? */
581 assert ( e->e_id != NOID );
582 assert ( e->e_id != 0 );
585 LDAP_LOG ( TOOLS, ARGS, "=> bdb_tool_entry_put( %ld, \"%s\" )\n",
586 (long) e->e_id, e->e_dn, 0 );
588 Debug( LDAP_DEBUG_TRACE, "=> bdb_tool_entry_put( %ld, \"%s\" )\n",
589 (long) e->e_id, e->e_dn, 0 );
592 rc = TXN_BEGIN( bdb->bi_dbenv, NULL, &tid,
593 bdb->bi_db_opflags );
595 snprintf( text->bv_val, text->bv_len,
596 "txn_begin failed: %s (%d)",
597 db_strerror(rc), rc );
599 LDAP_LOG ( TOOLS, ERR, "=> bdb_tool_entry_put: %s\n", text->bv_val, 0, 0 );
601 Debug( LDAP_DEBUG_ANY,
602 "=> bdb_tool_entry_put: %s\n",
603 text->bv_val, 0, 0 );
609 op.o_tmpmemctx = NULL;
610 op.o_tmpmfuncs = &ch_mfuncs;
613 rc = bdb_id2entry_update( be, tid, e );
615 snprintf( text->bv_val, text->bv_len,
616 "id2entry_add failed: %s (%d)",
617 db_strerror(rc), rc );
619 LDAP_LOG ( TOOLS, ERR,
620 "=> bdb_tool_entry_put: %s\n", text->bv_val, 0, 0 );
622 Debug( LDAP_DEBUG_ANY,
623 "=> bdb_tool_entry_put: %s\n", text->bv_val, 0, 0 );
628 rc = bdb_index_entry_del( &op, tid, e );
630 snprintf( text->bv_val, text->bv_len,
631 "index_entry_del failed: %s (%d)",
632 db_strerror(rc), rc );
634 LDAP_LOG ( TOOLS, ERR,
635 "=> bdb_tool_entry_put: %s\n", text->bv_val, 0, 0 );
637 Debug( LDAP_DEBUG_ANY,
638 "=> bdb_tool_entry_put: %s\n", text->bv_val, 0, 0 );
643 rc = bdb_index_entry_add( &op, tid, e );
645 snprintf( text->bv_val, text->bv_len,
646 "index_entry_add failed: %s (%d)",
647 db_strerror(rc), rc );
649 LDAP_LOG ( TOOLS, ERR,
650 "=> bdb_tool_entry_put: %s\n", text->bv_val, 0, 0 );
652 Debug( LDAP_DEBUG_ANY,
653 "=> bdb_tool_entry_put: %s\n", text->bv_val, 0, 0 );
660 rc = TXN_COMMIT( tid, 0 );
662 snprintf( text->bv_val, text->bv_len,
663 "txn_commit failed: %s (%d)",
664 db_strerror(rc), rc );
666 LDAP_LOG ( TOOLS, ERR,
667 "=> bdb_tool_entry_put: %s\n", text->bv_val, 0, 0 );
669 Debug( LDAP_DEBUG_ANY,
670 "=> bdb_tool_entry_put: %s\n",
671 text->bv_val, 0, 0 );
678 snprintf( text->bv_val, text->bv_len,
679 "txn_aborted! %s (%d)",
680 db_strerror(rc), rc );
682 LDAP_LOG ( TOOLS, ERR,
683 "=> bdb_tool_entry_put: %s\n", text->bv_val, 0, 0 );
685 Debug( LDAP_DEBUG_ANY,
686 "=> bdb_tool_entry_put: %s\n",
687 text->bv_val, 0, 0 );