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 Avlnode *index_attrs, index_dummy;
40 int bdb_tool_entry_open(
41 BackendDB *be, int mode )
43 /* initialize key and data thangs */
46 key.flags = DB_DBT_REALLOC;
47 data.flags = DB_DBT_REALLOC;
52 int bdb_tool_entry_close(
67 cursor->c_close( cursor );
73 fprintf( stderr, "Error, entries missing!\n");
74 for (i=0; i<nholes; i++) {
75 fprintf(stderr, " entry %ld: %s\n",
76 holes[i].id, holes[i].dn.bv_val);
84 static int bdb_reindex_cmp(const void *a, const void *b) { return 0; }
86 ID bdb_tool_entry_next(
91 struct bdb_info *bdb = (struct bdb_info *) be->be_private;
94 assert( slapMode & SLAP_TOOL_MODE );
95 assert( bdb != NULL );
99 rc = bdb->bi_id2entry->bdi_db->cursor(
100 bdb->bi_id2entry->bdi_db, NULL, &cursor,
101 bdb->bi_db_opflags );
107 rc = cursor->c_get( cursor, &key, &data, DB_NEXT );
110 /* If we're doing linear indexing and there are more attrs to
111 * index, and we're at the end of the database, start over.
113 if ( bdb->bi_attrs == &index_dummy ) {
114 if ( index_attrs && rc == DB_NOTFOUND ) {
115 /* optional - do a checkpoint here? */
116 index_dummy.avl_data = avl_delete(&index_attrs, NULL, bdb_reindex_cmp);
117 rc = cursor->c_get( cursor, &key, &data, DB_FIRST );
120 bdb->bi_attrs = NULL;
128 if( data.data == NULL ) {
132 AC_MEMCPY( &id, key.data, key.size );
136 ID bdb_tool_dn2id_get(
147 op.o_tmpmemctx = NULL;
148 op.o_tmpmfuncs = &ch_mfuncs;
150 bdb_dn2id( &op, NULL, dn, &ei );
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;
190 op.o_tmpmemctx = NULL;
191 op.o_tmpmfuncs = &ch_mfuncs;
193 rc = bdb_cache_find_id( &op, NULL, id, &ei, 0, 0, NULL );
194 if ( rc == LDAP_SUCCESS )
201 static int bdb_tool_next_id(
208 struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
209 struct berval dn = e->e_name;
210 struct berval ndn = e->e_nname;
211 struct berval pdn, npdn;
212 EntryInfo *ei = NULL;
215 if (ndn.bv_len == 0) return 0;
217 rc = bdb_cache_find_ndn( op, tid, &ndn, &ei );
218 if ( ei ) bdb_cache_entryinfo_unlock( ei );
219 if ( rc == DB_NOTFOUND ) {
220 if ( !be_issuffix( op->o_bd, &ndn ) ) {
221 dnParent( &dn, &pdn );
222 dnParent( &ndn, &npdn );
225 rc = bdb_tool_next_id( op, tid, e, text, 1 );
232 rc = bdb_next_id( op->o_bd, tid, &e->e_id );
234 snprintf( text->bv_val, text->bv_len,
235 "next_id failed: %s (%d)",
236 db_strerror(rc), rc );
237 Debug( LDAP_DEBUG_ANY,
238 "=> bdb_tool_next_id: %s\n", text->bv_val, 0, 0 );
241 rc = bdb_dn2id_add( op, tid, ei, e );
243 snprintf( text->bv_val, text->bv_len,
244 "dn2id_add failed: %s (%d)",
245 db_strerror(rc), rc );
246 Debug( LDAP_DEBUG_ANY,
247 "=> bdb_tool_next_id: %s\n", text->bv_val, 0, 0 );
249 if ( nholes == nhmax - 1 ) {
250 if ( holes == hbuf ) {
251 holes = ch_malloc( nhmax * sizeof(dn_id) * 2 );
252 AC_MEMCPY( holes, hbuf, sizeof(hbuf) );
254 holes = ch_realloc( holes, nhmax * sizeof(dn_id) * 2 );
258 ber_dupbv( &holes[nholes].dn, &ndn );
259 holes[nholes++].id = e->e_id;
261 } else if ( !hole ) {
264 e->e_id = ei->bei_id;
266 for ( i=0; i<nholes; i++) {
267 if ( holes[i].id == e->e_id ) {
269 free(holes[i].dn.bv_val);
270 for (j=i;j<nholes;j++) holes[j] = holes[j+1];
274 } else if ( holes[i].id > e->e_id ) {
282 ID bdb_tool_entry_put(
285 struct berval *text )
288 struct bdb_info *bdb = (struct bdb_info *) be->be_private;
293 assert( be != NULL );
294 assert( slapMode & SLAP_TOOL_MODE );
297 assert( text->bv_val );
298 assert( text->bv_val[0] == '\0' ); /* overconservative? */
300 Debug( LDAP_DEBUG_TRACE, "=> " LDAP_XSTRING(bdb_tool_entry_put)
301 "( %ld, \"%s\" )\n", (long) e->e_id, e->e_dn, 0 );
303 rc = TXN_BEGIN( bdb->bi_dbenv, NULL, &tid,
304 bdb->bi_db_opflags );
306 snprintf( text->bv_val, text->bv_len,
307 "txn_begin failed: %s (%d)",
308 db_strerror(rc), rc );
309 Debug( LDAP_DEBUG_ANY,
310 "=> " LDAP_XSTRING(bdb_tool_entry_put) ": %s\n",
311 text->bv_val, 0, 0 );
317 op.o_tmpmemctx = NULL;
318 op.o_tmpmfuncs = &ch_mfuncs;
320 /* add dn2id indices */
321 rc = bdb_tool_next_id( &op, tid, e, text, 0 );
327 rc = bdb_id2entry_add( be, tid, e );
329 snprintf( text->bv_val, text->bv_len,
330 "id2entry_add failed: %s (%d)",
331 db_strerror(rc), rc );
332 Debug( LDAP_DEBUG_ANY,
333 "=> " LDAP_XSTRING(bdb_tool_entry_put) ": %s\n",
334 text->bv_val, 0, 0 );
338 if ( !bdb->bi_linear_index )
339 rc = bdb_index_entry_add( &op, tid, e );
341 snprintf( text->bv_val, text->bv_len,
342 "index_entry_add failed: %s (%d)",
343 db_strerror(rc), rc );
344 Debug( LDAP_DEBUG_ANY,
345 "=> " LDAP_XSTRING(bdb_tool_entry_put) ": %s\n",
346 text->bv_val, 0, 0 );
352 rc = TXN_COMMIT( tid, 0 );
354 snprintf( text->bv_val, text->bv_len,
355 "txn_commit failed: %s (%d)",
356 db_strerror(rc), rc );
357 Debug( LDAP_DEBUG_ANY,
358 "=> " LDAP_XSTRING(bdb_tool_entry_put) ": %s\n",
359 text->bv_val, 0, 0 );
365 snprintf( text->bv_val, text->bv_len,
366 "txn_aborted! %s (%d)",
367 db_strerror(rc), rc );
368 Debug( LDAP_DEBUG_ANY,
369 "=> " LDAP_XSTRING(bdb_tool_entry_put) ": %s\n",
370 text->bv_val, 0, 0 );
377 int bdb_tool_entry_reindex(
381 struct bdb_info *bi = (struct bdb_info *) be->be_private;
388 Debug( LDAP_DEBUG_ARGS,
389 "=> " LDAP_XSTRING(bdb_tool_entry_reindex) "( %ld )\n",
392 /* No indexes configured, nothing to do. Could return an
393 * error here to shortcut things.
399 /* Get the first attribute to index */
400 if (bi->bi_linear_index && !index_attrs && bi->bi_attrs != &index_dummy) {
401 index_attrs = bi->bi_attrs;
402 bi->bi_attrs = &index_dummy;
403 index_dummy.avl_data = avl_delete(&index_attrs, NULL, bdb_reindex_cmp);
406 e = bdb_tool_entry_get( be, id );
409 Debug( LDAP_DEBUG_ANY,
410 LDAP_XSTRING(bdb_tool_entry_reindex)
411 ": could not locate id=%ld\n",
416 rc = TXN_BEGIN( bi->bi_dbenv, NULL, &tid, bi->bi_db_opflags );
418 Debug( LDAP_DEBUG_ANY,
419 "=> " LDAP_XSTRING(bdb_tool_entry_reindex) ": "
420 "txn_begin failed: %s (%d)\n",
421 db_strerror(rc), rc, 0 );
426 * just (re)add them for now
427 * assume that some other routine (not yet implemented)
428 * will zap index databases
432 Debug( LDAP_DEBUG_TRACE,
433 "=> " LDAP_XSTRING(bdb_tool_entry_reindex) "( %ld, \"%s\" )\n",
434 (long) id, e->e_dn, 0 );
438 op.o_tmpmemctx = NULL;
439 op.o_tmpmfuncs = &ch_mfuncs;
441 #if 0 /* ndef BDB_HIER */
442 /* add dn2id indices */
443 rc = bdb_dn2id_add( &op, tid, NULL, e );
444 if( rc != 0 && rc != DB_KEYEXIST ) {
445 Debug( LDAP_DEBUG_ANY,
446 "=> " LDAP_XSTRING(bdb_tool_entry_reindex)
447 ": dn2id_add failed: %s (%d)\n",
448 db_strerror(rc), rc, 0 );
453 rc = bdb_index_entry_add( &op, tid, e );
457 rc = TXN_COMMIT( tid, 0 );
459 Debug( LDAP_DEBUG_ANY,
460 "=> " LDAP_XSTRING(bdb_tool_entry_reindex)
461 ": txn_commit failed: %s (%d)\n",
462 db_strerror(rc), rc, 0 );
468 Debug( LDAP_DEBUG_ANY,
469 "=> " LDAP_XSTRING(bdb_tool_entry_reindex)
470 ": txn_aborted! %s (%d)\n",
471 db_strerror(rc), rc, 0 );
474 bdb_entry_release( &op, e, 0 );
479 ID bdb_tool_entry_modify(
482 struct berval *text )
485 struct bdb_info *bdb = (struct bdb_info *) be->be_private;
490 assert( be != NULL );
491 assert( slapMode & SLAP_TOOL_MODE );
494 assert( text->bv_val );
495 assert( text->bv_val[0] == '\0' ); /* overconservative? */
497 assert ( e->e_id != NOID );
498 assert ( e->e_id != 0 );
500 Debug( LDAP_DEBUG_TRACE,
501 "=> " LDAP_XSTRING(bdb_tool_entry_modify) "( %ld, \"%s\" )\n",
502 (long) e->e_id, e->e_dn, 0 );
504 rc = TXN_BEGIN( bdb->bi_dbenv, NULL, &tid,
505 bdb->bi_db_opflags );
507 snprintf( text->bv_val, text->bv_len,
508 "txn_begin failed: %s (%d)",
509 db_strerror(rc), rc );
510 Debug( LDAP_DEBUG_ANY,
511 "=> " LDAP_XSTRING(bdb_tool_entry_modify) ": %s\n",
512 text->bv_val, 0, 0 );
518 op.o_tmpmemctx = NULL;
519 op.o_tmpmfuncs = &ch_mfuncs;
522 rc = bdb_id2entry_update( be, tid, e );
524 snprintf( text->bv_val, text->bv_len,
525 "id2entry_add failed: %s (%d)",
526 db_strerror(rc), rc );
527 Debug( LDAP_DEBUG_ANY,
528 "=> " LDAP_XSTRING(bdb_tool_entry_modify) ": %s\n",
529 text->bv_val, 0, 0 );
533 rc = bdb_index_entry_del( &op, tid, e );
535 snprintf( text->bv_val, text->bv_len,
536 "index_entry_del failed: %s (%d)",
537 db_strerror(rc), rc );
538 Debug( LDAP_DEBUG_ANY,
539 "=> " LDAP_XSTRING(bdb_tool_entry_modify) ": %s\n",
540 text->bv_val, 0, 0 );
544 rc = bdb_index_entry_add( &op, tid, e );
546 snprintf( text->bv_val, text->bv_len,
547 "index_entry_add failed: %s (%d)",
548 db_strerror(rc), rc );
549 Debug( LDAP_DEBUG_ANY,
550 "=> " LDAP_XSTRING(bdb_tool_entry_modify) ": %s\n",
551 text->bv_val, 0, 0 );
557 rc = TXN_COMMIT( tid, 0 );
559 snprintf( text->bv_val, text->bv_len,
560 "txn_commit failed: %s (%d)",
561 db_strerror(rc), rc );
562 Debug( LDAP_DEBUG_ANY,
563 "=> " LDAP_XSTRING(bdb_tool_entry_modify) ": "
564 "%s\n", text->bv_val, 0, 0 );
570 snprintf( text->bv_val, text->bv_len,
571 "txn_aborted! %s (%d)",
572 db_strerror(rc), rc );
573 Debug( LDAP_DEBUG_ANY,
574 "=> " LDAP_XSTRING(bdb_tool_entry_modify) ": %s\n",
575 text->bv_val, 0, 0 );