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>
25 static DBC *cursor = NULL;
28 typedef struct dn_id {
33 #define HOLE_SIZE 4096
34 static dn_id hbuf[HOLE_SIZE], *holes = hbuf;
35 static unsigned nhmax = HOLE_SIZE;
36 static unsigned nholes;
38 int bdb_tool_entry_open(
39 BackendDB *be, int mode )
41 /* initialize key and data thangs */
44 key.flags = DB_DBT_REALLOC;
45 data.flags = DB_DBT_REALLOC;
50 int bdb_tool_entry_close(
65 cursor->c_close( cursor );
71 fprintf( stderr, "Error, entries missing!\n");
72 for (i=0; i<nholes; i++) {
73 fprintf(stderr, " entry %ld: %s\n",
74 holes[i].id, holes[i].dn.bv_val);
82 ID bdb_tool_entry_next(
87 struct bdb_info *bdb = (struct bdb_info *) be->be_private;
90 assert( slapMode & SLAP_TOOL_MODE );
91 assert( bdb != NULL );
94 rc = bdb->bi_id2entry->bdi_db->cursor(
95 bdb->bi_id2entry->bdi_db, NULL, &cursor,
102 rc = cursor->c_get( cursor, &key, &data, DB_NEXT );
108 if( data.data == NULL ) {
112 AC_MEMCPY( &id, key.data, key.size );
116 ID bdb_tool_dn2id_get(
121 struct bdb_info *bdb = (struct bdb_info *) be->be_private;
122 DB *db = bdb->bi_dn2id->bdi_db;
128 key.size = dn->bv_len + 2;
129 key.data = ch_malloc( key.size );
130 ((char*)key.data)[0] = DN_BASE_PREFIX;
131 AC_MEMCPY( &((char*)key.data)[1], dn->bv_val, key.size - 1 );
135 data.ulen = sizeof(ID);
136 data.flags = DB_DBT_USERMEM;
138 rc = db->get( db, NULL, &key, &data, bdb->bi_db_opflags );
142 LDAP_LOG ( INDEX, ERR, "bdb_tool_dn2id_get: get failed %s (%d)\n",
143 db_strerror(rc), rc, 0 );
145 Debug( LDAP_DEBUG_TRACE, "bdb_tool_dn2id_get: get failed: %s (%d)\n",
146 db_strerror( rc ), rc, 0 );
155 int bdb_tool_id2entry_get(
161 return bdb_id2entry( be, NULL, id, e );
164 Entry* bdb_tool_entry_get( BackendDB *be, ID id )
170 assert( be != NULL );
171 assert( slapMode & SLAP_TOOL_MODE );
172 assert( data.data != NULL );
175 DBT2bv( &data, &bv );
177 rc = entry_decode( &bv, &e );
179 if( rc == LDAP_SUCCESS ) {
184 EntryInfo *ei = NULL;
188 op.o_tmpmemctx = NULL;
189 op.o_tmpmfuncs = &ch_mfuncs;
191 rc = bdb_cache_find_id( &op, NULL, id, &ei, 0, 0, NULL );
192 if ( rc == LDAP_SUCCESS )
199 static int bdb_tool_next_id(
206 struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
207 struct berval dn = e->e_name;
208 struct berval ndn = e->e_nname;
209 struct berval pdn, npdn;
210 EntryInfo *ei = NULL;
213 if (ndn.bv_len == 0) return 0;
215 rc = bdb_cache_find_ndn( op, tid, &ndn, &ei );
216 if ( ei ) bdb_cache_entryinfo_unlock( ei );
217 if ( rc == DB_NOTFOUND ) {
218 if ( !be_issuffix( op->o_bd, &ndn ) ) {
219 dnParent( &dn, &pdn );
220 dnParent( &ndn, &npdn );
223 rc = bdb_tool_next_id( op, tid, e, text, 1 );
230 rc = bdb_next_id( op->o_bd, tid, &e->e_id );
232 snprintf( text->bv_val, text->bv_len,
233 "next_id failed: %s (%d)",
234 db_strerror(rc), rc );
236 LDAP_LOG ( TOOLS, ERR,
237 "=> bdb_tool_next_id: %s\n", text->bv_val, 0, 0 );
239 Debug( LDAP_DEBUG_ANY,
240 "=> bdb_tool_next_id: %s\n", text->bv_val, 0, 0 );
244 rc = bdb_dn2id_add( op, tid, ei, e );
246 snprintf( text->bv_val, text->bv_len,
247 "dn2id_add failed: %s (%d)",
248 db_strerror(rc), rc );
250 LDAP_LOG ( TOOLS, ERR,
251 "=> bdb_tool_next_id: %s\n", text->bv_val, 0, 0 );
253 Debug( LDAP_DEBUG_ANY,
254 "=> bdb_tool_next_id: %s\n", text->bv_val, 0, 0 );
257 if ( nholes == nhmax - 1 ) {
258 if ( holes == hbuf ) {
259 holes = ch_malloc( nhmax * sizeof(dn_id) * 2 );
260 AC_MEMCPY( holes, hbuf, sizeof(hbuf) );
262 holes = ch_realloc( holes, nhmax * sizeof(dn_id) * 2 );
266 ber_dupbv( &holes[nholes].dn, &ndn );
267 holes[nholes++].id = e->e_id;
269 } else if ( !hole ) {
272 e->e_id = ei->bei_id;
274 for ( i=0; i<nholes; i++) {
275 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 ) {
290 ID bdb_tool_entry_put(
293 struct berval *text )
296 struct bdb_info *bdb = (struct bdb_info *) be->be_private;
300 assert( be != NULL );
301 assert( slapMode & SLAP_TOOL_MODE );
304 assert( text->bv_val );
305 assert( text->bv_val[0] == '\0' ); /* overconservative? */
308 LDAP_LOG ( TOOLS, ARGS, "=> bdb_tool_entry_put( %ld, \"%s\" )\n",
309 (long) e->e_id, e->e_dn, 0 );
311 Debug( LDAP_DEBUG_TRACE, "=> bdb_tool_entry_put( %ld, \"%s\" )\n",
312 (long) e->e_id, e->e_dn, 0 );
315 rc = TXN_BEGIN( bdb->bi_dbenv, NULL, &tid,
316 bdb->bi_db_opflags );
318 snprintf( text->bv_val, text->bv_len,
319 "txn_begin failed: %s (%d)",
320 db_strerror(rc), rc );
322 LDAP_LOG ( TOOLS, ERR, "=> bdb_tool_entry_put: %s\n", text->bv_val, 0, 0 );
324 Debug( LDAP_DEBUG_ANY,
325 "=> bdb_tool_entry_put: %s\n",
326 text->bv_val, 0, 0 );
332 op.o_tmpmemctx = NULL;
333 op.o_tmpmfuncs = &ch_mfuncs;
335 /* add dn2id indices */
336 rc = bdb_tool_next_id( &op, tid, e, text, 0 );
342 rc = bdb_id2entry_add( be, tid, e );
344 snprintf( text->bv_val, text->bv_len,
345 "id2entry_add failed: %s (%d)",
346 db_strerror(rc), rc );
348 LDAP_LOG ( TOOLS, ERR,
349 "=> bdb_tool_entry_put: %s\n", text->bv_val, 0, 0 );
351 Debug( LDAP_DEBUG_ANY,
352 "=> bdb_tool_entry_put: %s\n", text->bv_val, 0, 0 );
357 rc = bdb_index_entry_add( &op, tid, e );
359 snprintf( text->bv_val, text->bv_len,
360 "index_entry_add failed: %s (%d)",
361 db_strerror(rc), rc );
363 LDAP_LOG ( TOOLS, ERR,
364 "=> bdb_tool_entry_put: %s\n", text->bv_val, 0, 0 );
366 Debug( LDAP_DEBUG_ANY,
367 "=> bdb_tool_entry_put: %s\n", text->bv_val, 0, 0 );
374 rc = TXN_COMMIT( tid, 0 );
376 snprintf( text->bv_val, text->bv_len,
377 "txn_commit failed: %s (%d)",
378 db_strerror(rc), rc );
380 LDAP_LOG ( TOOLS, ERR,
381 "=> bdb_tool_entry_put: %s\n", text->bv_val, 0, 0 );
383 Debug( LDAP_DEBUG_ANY,
384 "=> bdb_tool_entry_put: %s\n",
385 text->bv_val, 0, 0 );
392 snprintf( text->bv_val, text->bv_len,
393 "txn_aborted! %s (%d)",
394 db_strerror(rc), rc );
396 LDAP_LOG ( TOOLS, ERR,
397 "=> bdb_tool_entry_put: %s\n", text->bv_val, 0, 0 );
399 Debug( LDAP_DEBUG_ANY,
400 "=> bdb_tool_entry_put: %s\n",
401 text->bv_val, 0, 0 );
409 int bdb_tool_entry_reindex(
413 struct bdb_info *bi = (struct bdb_info *) be->be_private;
420 LDAP_LOG ( TOOLS, ARGS,
421 "=> bdb_tool_entry_reindex( %ld )\n", (long) id, 0, 0 );
423 Debug( LDAP_DEBUG_ARGS, "=> bdb_tool_entry_reindex( %ld )\n",
427 e = bdb_tool_entry_get( be, id );
431 LDAP_LOG ( TOOLS, DETAIL1,
432 "bdb_tool_entry_reindex:: could not locate id=%ld\n",
435 Debug( LDAP_DEBUG_ANY,
436 "bdb_tool_entry_reindex:: could not locate id=%ld\n",
442 rc = TXN_BEGIN( bi->bi_dbenv, NULL, &tid, bi->bi_db_opflags );
445 LDAP_LOG ( TOOLS, ERR,
446 "=> bdb_tool_entry_reindex: txn_begin failed: %s (%d)\n",
447 db_strerror(rc), rc, 0 );
449 Debug( LDAP_DEBUG_ANY,
450 "=> bdb_tool_entry_reindex: txn_begin failed: %s (%d)\n",
451 db_strerror(rc), rc, 0 );
457 * just (re)add them for now
458 * assume that some other routine (not yet implemented)
459 * will zap index databases
464 LDAP_LOG ( TOOLS, ERR,
465 "=> bdb_tool_entry_reindex( %ld, \"%s\" )\n", (long) id, e->e_dn, 0 );
467 Debug( LDAP_DEBUG_TRACE, "=> bdb_tool_entry_reindex( %ld, \"%s\" )\n",
468 (long) id, e->e_dn, 0 );
472 op.o_tmpmemctx = NULL;
473 op.o_tmpmfuncs = &ch_mfuncs;
476 /* add dn2id indices */
477 rc = bdb_dn2id_add( &op, tid, NULL, e );
478 if( rc != 0 && rc != DB_KEYEXIST ) {
480 LDAP_LOG ( TOOLS, ERR,
481 "=> bdb_tool_entry_reindex: dn2id_add failed: %s (%d)\n",
482 db_strerror(rc), rc, 0 );
484 Debug( LDAP_DEBUG_ANY,
485 "=> bdb_tool_entry_reindex: dn2id_add failed: %s (%d)\n",
486 db_strerror(rc), rc, 0 );
492 rc = bdb_index_entry_add( &op, tid, e );
496 rc = TXN_COMMIT( tid, 0 );
499 LDAP_LOG ( TOOLS, ERR,
500 "=> bdb_tool_entry_reindex: txn_commit failed: %s (%d)\n",
501 db_strerror(rc), rc, 0 );
503 Debug( LDAP_DEBUG_ANY,
504 "=> bdb_tool_entry_reindex: txn_commit failed: %s (%d)\n",
505 db_strerror(rc), rc, 0 );
513 LDAP_LOG ( TOOLS, DETAIL1,
514 "=> bdb_tool_entry_reindex: txn_aborted! %s (%d)\n",
515 db_strerror(rc), rc, 0 );
517 Debug( LDAP_DEBUG_ANY,
518 "=> bdb_tool_entry_reindex: txn_aborted! %s (%d)\n",
519 db_strerror(rc), rc, 0 );
523 bdb_entry_release( &op, e, 0 );
528 ID bdb_tool_entry_modify(
531 struct berval *text )
534 struct bdb_info *bdb = (struct bdb_info *) be->be_private;
538 assert( be != NULL );
539 assert( slapMode & SLAP_TOOL_MODE );
542 assert( text->bv_val );
543 assert( text->bv_val[0] == '\0' ); /* overconservative? */
545 assert ( e->e_id != NOID );
546 assert ( e->e_id != 0 );
549 LDAP_LOG ( TOOLS, ARGS, "=> bdb_tool_entry_put( %ld, \"%s\" )\n",
550 (long) e->e_id, e->e_dn, 0 );
552 Debug( LDAP_DEBUG_TRACE, "=> bdb_tool_entry_put( %ld, \"%s\" )\n",
553 (long) e->e_id, e->e_dn, 0 );
556 rc = TXN_BEGIN( bdb->bi_dbenv, NULL, &tid,
557 bdb->bi_db_opflags );
559 snprintf( text->bv_val, text->bv_len,
560 "txn_begin failed: %s (%d)",
561 db_strerror(rc), rc );
563 LDAP_LOG ( TOOLS, ERR, "=> bdb_tool_entry_put: %s\n", text->bv_val, 0, 0 );
565 Debug( LDAP_DEBUG_ANY,
566 "=> bdb_tool_entry_put: %s\n",
567 text->bv_val, 0, 0 );
573 op.o_tmpmemctx = NULL;
574 op.o_tmpmfuncs = &ch_mfuncs;
577 rc = bdb_id2entry_update( be, tid, e );
579 snprintf( text->bv_val, text->bv_len,
580 "id2entry_add failed: %s (%d)",
581 db_strerror(rc), rc );
583 LDAP_LOG ( TOOLS, ERR,
584 "=> bdb_tool_entry_put: %s\n", text->bv_val, 0, 0 );
586 Debug( LDAP_DEBUG_ANY,
587 "=> bdb_tool_entry_put: %s\n", text->bv_val, 0, 0 );
592 rc = bdb_index_entry_del( &op, tid, e );
594 snprintf( text->bv_val, text->bv_len,
595 "index_entry_del failed: %s (%d)",
596 db_strerror(rc), rc );
598 LDAP_LOG ( TOOLS, ERR,
599 "=> bdb_tool_entry_put: %s\n", text->bv_val, 0, 0 );
601 Debug( LDAP_DEBUG_ANY,
602 "=> bdb_tool_entry_put: %s\n", text->bv_val, 0, 0 );
607 rc = bdb_index_entry_add( &op, tid, e );
609 snprintf( text->bv_val, text->bv_len,
610 "index_entry_add failed: %s (%d)",
611 db_strerror(rc), rc );
613 LDAP_LOG ( TOOLS, ERR,
614 "=> bdb_tool_entry_put: %s\n", text->bv_val, 0, 0 );
616 Debug( LDAP_DEBUG_ANY,
617 "=> bdb_tool_entry_put: %s\n", text->bv_val, 0, 0 );
624 rc = TXN_COMMIT( tid, 0 );
626 snprintf( text->bv_val, text->bv_len,
627 "txn_commit failed: %s (%d)",
628 db_strerror(rc), rc );
630 LDAP_LOG ( TOOLS, ERR,
631 "=> bdb_tool_entry_put: %s\n", text->bv_val, 0, 0 );
633 Debug( LDAP_DEBUG_ANY,
634 "=> bdb_tool_entry_put: %s\n",
635 text->bv_val, 0, 0 );
642 snprintf( text->bv_val, text->bv_len,
643 "txn_aborted! %s (%d)",
644 db_strerror(rc), rc );
646 LDAP_LOG ( TOOLS, ERR,
647 "=> bdb_tool_entry_put: %s\n", text->bv_val, 0, 0 );
649 Debug( LDAP_DEBUG_ANY,
650 "=> bdb_tool_entry_put: %s\n",
651 text->bv_val, 0, 0 );