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(
141 struct bdb_info *bdb = (struct bdb_info *) be->be_private;
142 DB *db = bdb->bi_dn2id->bdi_db;
148 key.size = dn->bv_len + 2;
149 key.data = ch_malloc( key.size );
150 ((char*)key.data)[0] = DN_BASE_PREFIX;
151 AC_MEMCPY( &((char*)key.data)[1], dn->bv_val, key.size - 1 );
155 data.ulen = sizeof(ID);
156 data.flags = DB_DBT_USERMEM;
158 rc = db->get( db, NULL, &key, &data, bdb->bi_db_opflags );
161 Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_tool_dn2id_get)
162 ": get failed: %s (%d)\n",
163 db_strerror( rc ), rc, 0 );
171 int bdb_tool_id2entry_get(
177 return bdb_id2entry( be, NULL, id, e );
180 Entry* bdb_tool_entry_get( BackendDB *be, ID id )
186 assert( be != NULL );
187 assert( slapMode & SLAP_TOOL_MODE );
188 assert( data.data != NULL );
191 DBT2bv( &data, &bv );
193 rc = entry_decode( &bv, &e );
195 if( rc == LDAP_SUCCESS ) {
200 EntryInfo *ei = NULL;
204 op.o_tmpmemctx = NULL;
205 op.o_tmpmfuncs = &ch_mfuncs;
207 rc = bdb_cache_find_id( &op, NULL, id, &ei, 0, 0, NULL );
208 if ( rc == LDAP_SUCCESS )
215 static int bdb_tool_next_id(
222 struct bdb_info *bdb = (struct bdb_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;
226 EntryInfo *ei = NULL;
229 if (ndn.bv_len == 0) return 0;
231 rc = bdb_cache_find_ndn( op, tid, &ndn, &ei );
232 if ( ei ) bdb_cache_entryinfo_unlock( ei );
233 if ( rc == DB_NOTFOUND ) {
234 if ( !be_issuffix( op->o_bd, &ndn ) ) {
235 dnParent( &dn, &pdn );
236 dnParent( &ndn, &npdn );
239 rc = bdb_tool_next_id( op, tid, e, text, 1 );
246 rc = bdb_next_id( op->o_bd, tid, &e->e_id );
248 snprintf( text->bv_val, text->bv_len,
249 "next_id failed: %s (%d)",
250 db_strerror(rc), rc );
251 Debug( LDAP_DEBUG_ANY,
252 "=> bdb_tool_next_id: %s\n", text->bv_val, 0, 0 );
255 rc = bdb_dn2id_add( op, tid, ei, e );
257 snprintf( text->bv_val, text->bv_len,
258 "dn2id_add failed: %s (%d)",
259 db_strerror(rc), rc );
260 Debug( LDAP_DEBUG_ANY,
261 "=> bdb_tool_next_id: %s\n", text->bv_val, 0, 0 );
263 if ( nholes == nhmax - 1 ) {
264 if ( holes == hbuf ) {
265 holes = ch_malloc( nhmax * sizeof(dn_id) * 2 );
266 AC_MEMCPY( holes, hbuf, sizeof(hbuf) );
268 holes = ch_realloc( holes, nhmax * sizeof(dn_id) * 2 );
272 ber_dupbv( &holes[nholes].dn, &ndn );
273 holes[nholes++].id = e->e_id;
275 } else if ( !hole ) {
278 e->e_id = ei->bei_id;
280 for ( i=0; i<nholes; i++) {
281 if ( holes[i].id == e->e_id ) {
283 free(holes[i].dn.bv_val);
284 for (j=i;j<nholes;j++) holes[j] = holes[j+1];
288 } else if ( holes[i].id > e->e_id ) {
296 ID bdb_tool_entry_put(
299 struct berval *text )
302 struct bdb_info *bdb = (struct bdb_info *) be->be_private;
306 assert( be != NULL );
307 assert( slapMode & SLAP_TOOL_MODE );
310 assert( text->bv_val );
311 assert( text->bv_val[0] == '\0' ); /* overconservative? */
313 Debug( LDAP_DEBUG_TRACE, "=> " LDAP_XSTRING(bdb_tool_entry_put)
314 "( %ld, \"%s\" )\n", (long) e->e_id, e->e_dn, 0 );
316 rc = TXN_BEGIN( bdb->bi_dbenv, NULL, &tid,
317 bdb->bi_db_opflags );
319 snprintf( text->bv_val, text->bv_len,
320 "txn_begin failed: %s (%d)",
321 db_strerror(rc), rc );
322 Debug( LDAP_DEBUG_ANY,
323 "=> " LDAP_XSTRING(bdb_tool_entry_put) ": %s\n",
324 text->bv_val, 0, 0 );
329 op.o_tmpmemctx = NULL;
330 op.o_tmpmfuncs = &ch_mfuncs;
332 /* add dn2id indices */
333 rc = bdb_tool_next_id( &op, tid, e, text, 0 );
339 rc = bdb_id2entry_add( be, tid, e );
341 snprintf( text->bv_val, text->bv_len,
342 "id2entry_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 );
350 if ( !bdb->bi_linear_index )
351 rc = bdb_index_entry_add( &op, tid, e );
353 snprintf( text->bv_val, text->bv_len,
354 "index_entry_add failed: %s (%d)",
355 db_strerror(rc), rc );
356 Debug( LDAP_DEBUG_ANY,
357 "=> " LDAP_XSTRING(bdb_tool_entry_put) ": %s\n",
358 text->bv_val, 0, 0 );
364 rc = TXN_COMMIT( tid, 0 );
366 snprintf( text->bv_val, text->bv_len,
367 "txn_commit failed: %s (%d)",
368 db_strerror(rc), rc );
369 Debug( LDAP_DEBUG_ANY,
370 "=> " LDAP_XSTRING(bdb_tool_entry_put) ": %s\n",
371 text->bv_val, 0, 0 );
377 snprintf( text->bv_val, text->bv_len,
378 "txn_aborted! %s (%d)",
379 db_strerror(rc), rc );
380 Debug( LDAP_DEBUG_ANY,
381 "=> " LDAP_XSTRING(bdb_tool_entry_put) ": %s\n",
382 text->bv_val, 0, 0 );
389 int bdb_tool_entry_reindex(
393 struct bdb_info *bi = (struct bdb_info *) be->be_private;
399 Debug( LDAP_DEBUG_ARGS,
400 "=> " LDAP_XSTRING(bdb_tool_entry_reindex) "( %ld )\n",
403 /* No indexes configured, nothing to do. Could return an
404 * error here to shortcut things.
410 /* Get the first attribute to index */
411 if (bi->bi_linear_index && !index_attrs && bi->bi_attrs != &index_dummy) {
412 index_attrs = bi->bi_attrs;
413 bi->bi_attrs = &index_dummy;
414 index_dummy.avl_data = avl_delete(&index_attrs, NULL, bdb_reindex_cmp);
417 e = bdb_tool_entry_get( be, id );
420 Debug( LDAP_DEBUG_ANY,
421 LDAP_XSTRING(bdb_tool_entry_reindex)
422 ": could not locate id=%ld\n",
427 rc = TXN_BEGIN( bi->bi_dbenv, NULL, &tid, bi->bi_db_opflags );
429 Debug( LDAP_DEBUG_ANY,
430 "=> " LDAP_XSTRING(bdb_tool_entry_reindex) ": "
431 "txn_begin failed: %s (%d)\n",
432 db_strerror(rc), rc, 0 );
437 * just (re)add them for now
438 * assume that some other routine (not yet implemented)
439 * will zap index databases
443 Debug( LDAP_DEBUG_TRACE,
444 "=> " LDAP_XSTRING(bdb_tool_entry_reindex) "( %ld, \"%s\" )\n",
445 (long) id, e->e_dn, 0 );
448 op.o_tmpmemctx = NULL;
449 op.o_tmpmfuncs = &ch_mfuncs;
451 #if 0 /* ndef BDB_HIER */
452 /* add dn2id indices */
453 rc = bdb_dn2id_add( &op, tid, NULL, e );
454 if( rc != 0 && rc != DB_KEYEXIST ) {
455 Debug( LDAP_DEBUG_ANY,
456 "=> " LDAP_XSTRING(bdb_tool_entry_reindex)
457 ": dn2id_add failed: %s (%d)\n",
458 db_strerror(rc), rc, 0 );
463 rc = bdb_index_entry_add( &op, tid, e );
467 rc = TXN_COMMIT( tid, 0 );
469 Debug( LDAP_DEBUG_ANY,
470 "=> " LDAP_XSTRING(bdb_tool_entry_reindex)
471 ": txn_commit failed: %s (%d)\n",
472 db_strerror(rc), rc, 0 );
478 Debug( LDAP_DEBUG_ANY,
479 "=> " LDAP_XSTRING(bdb_tool_entry_reindex)
480 ": txn_aborted! %s (%d)\n",
481 db_strerror(rc), rc, 0 );
484 bdb_entry_release( &op, e, 0 );
489 ID bdb_tool_entry_modify(
492 struct berval *text )
495 struct bdb_info *bdb = (struct bdb_info *) be->be_private;
499 assert( be != NULL );
500 assert( slapMode & SLAP_TOOL_MODE );
503 assert( text->bv_val );
504 assert( text->bv_val[0] == '\0' ); /* overconservative? */
506 assert ( e->e_id != NOID );
507 assert ( e->e_id != 0 );
509 Debug( LDAP_DEBUG_TRACE,
510 "=> " LDAP_XSTRING(bdb_tool_entry_modify) "( %ld, \"%s\" )\n",
511 (long) e->e_id, e->e_dn, 0 );
513 rc = TXN_BEGIN( bdb->bi_dbenv, NULL, &tid,
514 bdb->bi_db_opflags );
516 snprintf( text->bv_val, text->bv_len,
517 "txn_begin failed: %s (%d)",
518 db_strerror(rc), rc );
519 Debug( LDAP_DEBUG_ANY,
520 "=> " LDAP_XSTRING(bdb_tool_entry_modify) ": %s\n",
521 text->bv_val, 0, 0 );
526 op.o_tmpmemctx = NULL;
527 op.o_tmpmfuncs = &ch_mfuncs;
530 rc = bdb_id2entry_update( be, tid, e );
532 snprintf( text->bv_val, text->bv_len,
533 "id2entry_add failed: %s (%d)",
534 db_strerror(rc), rc );
535 Debug( LDAP_DEBUG_ANY,
536 "=> " LDAP_XSTRING(bdb_tool_entry_modify) ": %s\n",
537 text->bv_val, 0, 0 );
541 rc = bdb_index_entry_del( &op, tid, e );
543 snprintf( text->bv_val, text->bv_len,
544 "index_entry_del failed: %s (%d)",
545 db_strerror(rc), rc );
546 Debug( LDAP_DEBUG_ANY,
547 "=> " LDAP_XSTRING(bdb_tool_entry_modify) ": %s\n",
548 text->bv_val, 0, 0 );
552 rc = bdb_index_entry_add( &op, tid, e );
554 snprintf( text->bv_val, text->bv_len,
555 "index_entry_add failed: %s (%d)",
556 db_strerror(rc), rc );
557 Debug( LDAP_DEBUG_ANY,
558 "=> " LDAP_XSTRING(bdb_tool_entry_modify) ": %s\n",
559 text->bv_val, 0, 0 );
565 rc = TXN_COMMIT( tid, 0 );
567 snprintf( text->bv_val, text->bv_len,
568 "txn_commit failed: %s (%d)",
569 db_strerror(rc), rc );
570 Debug( LDAP_DEBUG_ANY,
571 "=> " LDAP_XSTRING(bdb_tool_entry_modify) ": "
572 "%s\n", text->bv_val, 0, 0 );
578 snprintf( text->bv_val, text->bv_len,
579 "txn_aborted! %s (%d)",
580 db_strerror(rc), rc );
581 Debug( LDAP_DEBUG_ANY,
582 "=> " LDAP_XSTRING(bdb_tool_entry_modify) ": %s\n",
583 text->bv_val, 0, 0 );