Back to index

openldap  2.4.31
Classes | Defines | Typedefs | Functions | Variables
tools.c File Reference
#include "portable.h"
#include <stdio.h>
#include <ac/string.h>
#include <ac/errno.h>
#include "back-bdb.h"
#include "idl.h"

Go to the source code of this file.

Classes

struct  dn_id

Defines

#define AVL_INTERNAL
#define HOLE_SIZE   4096

Typedefs

typedef struct dn_id dn_id

Functions

static voidbdb_tool_index_task (void *ctx, void *ptr)
static int bdb_tool_entry_get_int (BackendDB *be, ID id, Entry **ep)
int bdb_tool_entry_open (BackendDB *be, int mode)
int bdb_tool_entry_close (BackendDB *be)
ID bdb_tool_entry_first_x (BackendDB *be, struct berval *base, int scope, Filter *f)
ID bdb_tool_entry_next (BackendDB *be)
ID bdb_tool_dn2id_get (Backend *be, struct berval *dn)
Entrybdb_tool_entry_get (BackendDB *be, ID id)
static int bdb_tool_next_id (Operation *op, DB_TXN *tid, Entry *e, struct berval *text, int hole)
static int bdb_tool_index_add (Operation *op, DB_TXN *txn, Entry *e)
ID bdb_tool_entry_put (BackendDB *be, Entry *e, struct berval *text)
int bdb_tool_entry_reindex (BackendDB *be, ID id, AttributeDescription **adv)
ID bdb_tool_entry_modify (BackendDB *be, Entry *e, struct berval *text)

Variables

static DBC * cursor = NULL
static DBT key
static DBT data
static EntryHeader eh
static ID nid
static ID previd = NOID
static char ehbuf [16]
static dn_id hbuf [HOLE_SIZE]
static dn_idholes = hbuf
static unsigned nhmax = HOLE_SIZE
static unsigned nholes
static int index_nattrs
static struct bervaltool_base
static int tool_scope
static Filtertool_filter
static Entrytool_next_entry
static ID bdb_tool_ix_id
static Operationbdb_tool_ix_op
static intbdb_tool_index_threads
static int bdb_tool_index_tcount
static voidbdb_tool_index_rec
static struct bdb_infobdb_tool_info
static ldap_pvt_thread_mutex_t bdb_tool_index_mutex
static ldap_pvt_thread_cond_t bdb_tool_index_cond_main
static ldap_pvt_thread_cond_t bdb_tool_index_cond_work
static int bdb_tool_threads

Class Documentation

struct dn_id

Definition at line 33 of file tools.c.

Class Members
ID id

Define Documentation

#define AVL_INTERNAL

Definition at line 23 of file tools.c.

#define HOLE_SIZE   4096

Definition at line 38 of file tools.c.


Typedef Documentation

typedef struct dn_id dn_id

Function Documentation

ID bdb_tool_dn2id_get ( Backend be,
struct berval dn 
)

Definition at line 334 of file tools.c.

{
       Operation op = {0};
       Opheader ohdr = {0};
       EntryInfo *ei = NULL;
       int rc;

       if ( BER_BVISEMPTY(dn) )
              return 0;

       op.o_hdr = &ohdr;
       op.o_bd = be;
       op.o_tmpmemctx = NULL;
       op.o_tmpmfuncs = &ch_mfuncs;

       rc = bdb_cache_find_ndn( &op, 0, dn, &ei );
       if ( ei ) bdb_cache_entryinfo_unlock( ei );
       if ( rc == DB_NOTFOUND )
              return NOID;
       
       return ei->bei_id;
}

Definition at line 163 of file tools.c.

{
       if ( bdb_tool_info ) {
              slapd_shutdown = 1;
#ifdef USE_TRICKLE
              ldap_pvt_thread_mutex_lock( &bdb_tool_trickle_mutex );

              /* trickle thread may not have started yet */
              while ( !bdb_tool_trickle_active )
                     ldap_pvt_thread_cond_wait( &bdb_tool_trickle_cond_end,
                                   &bdb_tool_trickle_mutex );

              ldap_pvt_thread_cond_signal( &bdb_tool_trickle_cond );
              while ( bdb_tool_trickle_active )
                     ldap_pvt_thread_cond_wait( &bdb_tool_trickle_cond_end,
                                   &bdb_tool_trickle_mutex );
              ldap_pvt_thread_mutex_unlock( &bdb_tool_trickle_mutex );
#endif
              if ( bdb_tool_threads > 1 ) {
                     ldap_pvt_thread_mutex_lock( &bdb_tool_index_mutex );

                     /* There might still be some threads starting */
                     while ( bdb_tool_index_tcount > 0 ) {
                            ldap_pvt_thread_cond_wait( &bdb_tool_index_cond_main,
                                          &bdb_tool_index_mutex );
                     }

                     bdb_tool_index_tcount = bdb_tool_threads - 1;
                     ldap_pvt_thread_cond_broadcast( &bdb_tool_index_cond_work );

                     /* Make sure all threads are stopped */
                     while ( bdb_tool_index_tcount > 0 ) {
                            ldap_pvt_thread_cond_wait( &bdb_tool_index_cond_main,
                                   &bdb_tool_index_mutex );
                     }
                     ldap_pvt_thread_mutex_unlock( &bdb_tool_index_mutex );

                     ch_free( bdb_tool_index_threads );
                     ch_free( bdb_tool_index_rec );
                     bdb_tool_index_tcount = bdb_tool_threads - 1;
              }
              bdb_tool_info = NULL;
              slapd_shutdown = 0;
       }

       if( eh.bv.bv_val ) {
              ch_free( eh.bv.bv_val );
              eh.bv.bv_val = NULL;
       }

       if( cursor ) {
              cursor->c_close( cursor );
              cursor = NULL;
       }

#ifdef BDB_TOOL_IDL_CACHING
       bdb_tool_idl_flush( be );
#endif

       if( nholes ) {
              unsigned i;
              fprintf( stderr, "Error, entries missing!\n");
              for (i=0; i<nholes; i++) {
                     fprintf(stderr, "  entry %ld: %s\n",
                            holes[i].id, holes[i].dn.bv_val);
              }
              return -1;
       }
                     
       return 0;
}

Here is the call graph for this function:

ID bdb_tool_entry_first_x ( BackendDB be,
struct berval base,
int  scope,
Filter f 
)

Definition at line 237 of file tools.c.

Entry* bdb_tool_entry_get ( BackendDB be,
ID  id 
)

Definition at line 480 of file tools.c.

{
       Entry *e = NULL;

       (void)bdb_tool_entry_get_int( be, id, &e );
       return e;
}

Here is the call graph for this function:

static int bdb_tool_entry_get_int ( BackendDB be,
ID  id,
Entry **  ep 
) [static]

Definition at line 361 of file tools.c.

{
       Entry *e = NULL;
       char *dptr;
       int rc, eoff;

       assert( be != NULL );
       assert( slapMode & SLAP_TOOL_MODE );

       if ( ( tool_filter || tool_base ) && id == previd && tool_next_entry != NULL ) {
              *ep = tool_next_entry;
              tool_next_entry = NULL;
              return LDAP_SUCCESS;
       }

       if ( id != previd ) {
              data.ulen = data.dlen = sizeof( ehbuf );
              data.data = ehbuf;
              data.flags |= DB_DBT_PARTIAL;

              BDB_ID2DISK( id, &nid );
              rc = cursor->c_get( cursor, &key, &data, DB_SET );
              if ( rc ) {
                     rc = LDAP_OTHER;
                     goto done;
              }
       }

       /* Get the header */
       dptr = eh.bv.bv_val;
       eh.bv.bv_val = ehbuf;
       eh.bv.bv_len = data.size;
       rc = entry_header( &eh );
       eoff = eh.data - eh.bv.bv_val;
       eh.bv.bv_val = dptr;
       if ( rc ) {
              rc = LDAP_OTHER;
              goto done;
       }

       /* Get the size */
       data.flags &= ~DB_DBT_PARTIAL;
       data.ulen = 0;
       rc = cursor->c_get( cursor, &key, &data, DB_CURRENT );
       if ( rc != DB_BUFFER_SMALL ) {
              rc = LDAP_OTHER;
              goto done;
       }

       /* Allocate a block and retrieve the data */
       eh.bv.bv_len = eh.nvals * sizeof( struct berval ) + data.size;
       eh.bv.bv_val = ch_realloc( eh.bv.bv_val, eh.bv.bv_len );
       eh.data = eh.bv.bv_val + eh.nvals * sizeof( struct berval );
       data.data = eh.data;
       data.ulen = data.size;

       /* Skip past already parsed nattr/nvals */
       eh.data += eoff;

       rc = cursor->c_get( cursor, &key, &data, DB_CURRENT );
       if ( rc ) {
              rc = LDAP_OTHER;
              goto done;
       }

#ifndef BDB_HIER
       /* TODO: handle BDB_HIER accordingly */
       if ( tool_base != NULL ) {
              struct berval ndn;
              entry_decode_dn( &eh, NULL, &ndn );

              if ( !dnIsSuffixScope( &ndn, tool_base, tool_scope ) ) {
                     return LDAP_NO_SUCH_OBJECT;
              }
       }
#endif

#ifdef SLAP_ZONE_ALLOC
       /* FIXME: will add ctx later */
       rc = entry_decode( &eh, &e, NULL );
#else
       rc = entry_decode( &eh, &e );
#endif

       if( rc == LDAP_SUCCESS ) {
              e->e_id = id;
#ifdef BDB_HIER
              if ( slapMode & SLAP_TOOL_READONLY ) {
                     struct bdb_info *bdb = (struct bdb_info *) be->be_private;
                     EntryInfo *ei = NULL;
                     Operation op = {0};
                     Opheader ohdr = {0};

                     op.o_hdr = &ohdr;
                     op.o_bd = be;
                     op.o_tmpmemctx = NULL;
                     op.o_tmpmfuncs = &ch_mfuncs;

                     rc = bdb_cache_find_parent( &op, bdb->bi_cache.c_txn, id, &ei );
                     if ( rc == LDAP_SUCCESS ) {
                            bdb_cache_entryinfo_unlock( ei );
                            e->e_private = ei;
                            ei->bei_e = e;
                            bdb_fix_dn( e, 0 );
                            ei->bei_e = NULL;
                            e->e_private = NULL;
                     }
              }
#endif
       }
done:
       if ( e != NULL ) {
              *ep = e;
       }

       return rc;
}

Here is the call graph for this function:

Here is the caller graph for this function:

ID bdb_tool_entry_modify ( BackendDB be,
Entry e,
struct berval text 
)

Definition at line 890 of file tools.c.

{
       int rc;
       struct bdb_info *bdb;
       DB_TXN *tid = NULL;
       Operation op = {0};
       Opheader ohdr = {0};

       assert( be != NULL );
       assert( slapMode & SLAP_TOOL_MODE );

       assert( text != NULL );
       assert( text->bv_val != NULL );
       assert( text->bv_val[0] == '\0' ); /* overconservative? */

       assert ( e->e_id != NOID );

       Debug( LDAP_DEBUG_TRACE,
              "=> " LDAP_XSTRING(bdb_tool_entry_modify) "( %ld, \"%s\" )\n",
              (long) e->e_id, e->e_dn, 0 );

       bdb = (struct bdb_info *) be->be_private;

       if (! (slapMode & SLAP_TOOL_QUICK)) {
              if( cursor ) {
                     cursor->c_close( cursor );
                     cursor = NULL;
              }
              rc = TXN_BEGIN( bdb->bi_dbenv, NULL, &tid, 
                     bdb->bi_db_opflags );
              if( rc != 0 ) {
                     snprintf( text->bv_val, text->bv_len,
                            "txn_begin failed: %s (%d)",
                            db_strerror(rc), rc );
                     Debug( LDAP_DEBUG_ANY,
                            "=> " LDAP_XSTRING(bdb_tool_entry_modify) ": %s\n",
                             text->bv_val, 0, 0 );
                     return NOID;
              }
       }

       op.o_hdr = &ohdr;
       op.o_bd = be;
       op.o_tmpmemctx = NULL;
       op.o_tmpmfuncs = &ch_mfuncs;

       /* id2entry index */
       rc = bdb_id2entry_update( be, tid, e );
       if( rc != 0 ) {
              snprintf( text->bv_val, text->bv_len,
                            "id2entry_add failed: %s (%d)",
                            db_strerror(rc), rc );
              Debug( LDAP_DEBUG_ANY,
                     "=> " LDAP_XSTRING(bdb_tool_entry_modify) ": %s\n",
                     text->bv_val, 0, 0 );
              goto done;
       }

done:
       if( rc == 0 ) {
              if (! (slapMode & SLAP_TOOL_QUICK)) {
              rc = TXN_COMMIT( tid, 0 );
              if( rc != 0 ) {
                     snprintf( text->bv_val, text->bv_len,
                                   "txn_commit failed: %s (%d)",
                                   db_strerror(rc), rc );
                     Debug( LDAP_DEBUG_ANY,
                            "=> " LDAP_XSTRING(bdb_tool_entry_modify) ": "
                            "%s\n", text->bv_val, 0, 0 );
                     e->e_id = NOID;
              }
              }

       } else {
              if (! (slapMode & SLAP_TOOL_QUICK)) {
              TXN_ABORT( tid );
              snprintf( text->bv_val, text->bv_len,
                     "txn_aborted! %s (%d)",
                     db_strerror(rc), rc );
              Debug( LDAP_DEBUG_ANY,
                     "=> " LDAP_XSTRING(bdb_tool_entry_modify) ": %s\n",
                     text->bv_val, 0, 0 );
              }
              e->e_id = NOID;
       }

       return e->e_id;
}

Here is the call graph for this function:

Definition at line 250 of file tools.c.

{
       int rc;
       ID id;
       struct bdb_info *bdb;

       assert( be != NULL );
       assert( slapMode & SLAP_TOOL_MODE );

       bdb = (struct bdb_info *) be->be_private;
       assert( bdb != NULL );

next:;
       /* Get the header */
       data.ulen = data.dlen = sizeof( ehbuf );
       data.data = ehbuf;
       data.flags |= DB_DBT_PARTIAL;
       rc = cursor->c_get( cursor, &key, &data, DB_NEXT );

       if( rc ) {
              /* If we're doing linear indexing and there are more attrs to
               * index, and we're at the end of the database, start over.
               */
              if ( index_nattrs && rc == DB_NOTFOUND ) {
                     /* optional - do a checkpoint here? */
                     bdb_attr_info_free( bdb->bi_attrs[0] );
                     bdb->bi_attrs[0] = bdb->bi_attrs[index_nattrs];
                     index_nattrs--;
                     rc = cursor->c_get( cursor, &key, &data, DB_FIRST );
                     if ( rc ) {
                            return NOID;
                     }
              } else {
                     return NOID;
              }
       }

       BDB_DISK2ID( key.data, &id );
       previd = id;

       if ( tool_filter || tool_base ) {
              static Operation op = {0};
              static Opheader ohdr = {0};

              op.o_hdr = &ohdr;
              op.o_bd = be;
              op.o_tmpmemctx = NULL;
              op.o_tmpmfuncs = &ch_mfuncs;

              if ( tool_next_entry ) {
                     bdb_entry_release( &op, tool_next_entry, 0 );
                     tool_next_entry = NULL;
              }

              rc = bdb_tool_entry_get_int( be, id, &tool_next_entry );
              if ( rc == LDAP_NO_SUCH_OBJECT ) {
                     goto next;
              }

              assert( tool_next_entry != NULL );

#ifdef BDB_HIER
              /* TODO: needed until BDB_HIER is handled accordingly
               * in bdb_tool_entry_get_int() */
              if ( tool_base && !dnIsSuffixScope( &tool_next_entry->e_nname, tool_base, tool_scope ) )
              {
                     bdb_entry_release( &op, tool_next_entry, 0 );
                     tool_next_entry = NULL;
                     goto next;
              }
#endif

              if ( tool_filter && test_filter( NULL, tool_next_entry, tool_filter ) != LDAP_COMPARE_TRUE )
              {
                     bdb_entry_release( &op, tool_next_entry, 0 );
                     tool_next_entry = NULL;
                     goto next;
              }
       }

       return id;
}

Here is the call graph for this function:

int bdb_tool_entry_open ( BackendDB be,
int  mode 
)

Definition at line 106 of file tools.c.

{
       struct bdb_info *bdb = (struct bdb_info *) be->be_private;

       /* initialize key and data thangs */
       DBTzero( &key );
       DBTzero( &data );
       key.flags = DB_DBT_USERMEM;
       key.data = &nid;
       key.size = key.ulen = sizeof( nid );
       data.flags = DB_DBT_USERMEM;

       if (cursor == NULL) {
              int rc = bdb->bi_id2entry->bdi_db->cursor(
                     bdb->bi_id2entry->bdi_db, bdb->bi_cache.c_txn, &cursor,
                     bdb->bi_db_opflags );
              if( rc != 0 ) {
                     return -1;
              }
       }

       /* Set up for threaded slapindex */
       if (( slapMode & (SLAP_TOOL_QUICK|SLAP_TOOL_READONLY)) == SLAP_TOOL_QUICK ) {
              if ( !bdb_tool_info ) {
#ifdef USE_TRICKLE
                     ldap_pvt_thread_mutex_init( &bdb_tool_trickle_mutex );
                     ldap_pvt_thread_cond_init( &bdb_tool_trickle_cond );
                     ldap_pvt_thread_cond_init( &bdb_tool_trickle_cond_end );
                     ldap_pvt_thread_pool_submit( &connection_pool, bdb_tool_trickle_task, bdb->bi_dbenv );
#endif

                     ldap_pvt_thread_mutex_init( &bdb_tool_index_mutex );
                     ldap_pvt_thread_cond_init( &bdb_tool_index_cond_main );
                     ldap_pvt_thread_cond_init( &bdb_tool_index_cond_work );
                     if ( bdb->bi_nattrs ) {
                            int i;
                            bdb_tool_threads = slap_tool_thread_max - 1;
                            if ( bdb_tool_threads > 1 ) {
                                   bdb_tool_index_threads = ch_malloc( bdb_tool_threads * sizeof( int ));
                                   bdb_tool_index_rec = ch_malloc( bdb->bi_nattrs * sizeof( IndexRec ));
                                   bdb_tool_index_tcount = bdb_tool_threads - 1;
                                   for (i=1; i<bdb_tool_threads; i++) {
                                          int *ptr = ch_malloc( sizeof( int ));
                                          *ptr = i;
                                          ldap_pvt_thread_pool_submit( &connection_pool,
                                                 bdb_tool_index_task, ptr );
                                   }
                            }
                     }
                     bdb_tool_info = bdb;
              }
       }

       return 0;
}

Here is the call graph for this function:

ID bdb_tool_entry_put ( BackendDB be,
Entry e,
struct berval text 
)

Definition at line 640 of file tools.c.

{
       int rc;
       struct bdb_info *bdb;
       DB_TXN *tid = NULL;
       Operation op = {0};
       Opheader ohdr = {0};

       assert( be != NULL );
       assert( slapMode & SLAP_TOOL_MODE );

       assert( text != NULL );
       assert( text->bv_val != NULL );
       assert( text->bv_val[0] == '\0' ); /* overconservative? */

       Debug( LDAP_DEBUG_TRACE, "=> " LDAP_XSTRING(bdb_tool_entry_put)
              "( %ld, \"%s\" )\n", (long) e->e_id, e->e_dn, 0 );

       bdb = (struct bdb_info *) be->be_private;

       if (! (slapMode & SLAP_TOOL_QUICK)) {
       rc = TXN_BEGIN( bdb->bi_dbenv, NULL, &tid, 
              bdb->bi_db_opflags );
       if( rc != 0 ) {
              snprintf( text->bv_val, text->bv_len,
                     "txn_begin failed: %s (%d)",
                     db_strerror(rc), rc );
              Debug( LDAP_DEBUG_ANY,
                     "=> " LDAP_XSTRING(bdb_tool_entry_put) ": %s\n",
                      text->bv_val, 0, 0 );
              return NOID;
       }
       }

       op.o_hdr = &ohdr;
       op.o_bd = be;
       op.o_tmpmemctx = NULL;
       op.o_tmpmfuncs = &ch_mfuncs;

       /* add dn2id indices */
       rc = bdb_tool_next_id( &op, tid, e, text, 0 );
       if( rc != 0 ) {
              goto done;
       }

#ifdef USE_TRICKLE
       if (( slapMode & SLAP_TOOL_QUICK ) && (( e->e_id & 0xfff ) == 0xfff )) {
              ldap_pvt_thread_cond_signal( &bdb_tool_trickle_cond );
       }
#endif

       if ( !bdb->bi_linear_index )
              rc = bdb_tool_index_add( &op, tid, e );
       if( rc != 0 ) {
              snprintf( text->bv_val, text->bv_len,
                            "index_entry_add failed: %s (%d)",
                            rc == LDAP_OTHER ? "Internal error" :
                            db_strerror(rc), rc );
              Debug( LDAP_DEBUG_ANY,
                     "=> " LDAP_XSTRING(bdb_tool_entry_put) ": %s\n",
                     text->bv_val, 0, 0 );
              goto done;
       }

       /* id2entry index */
       rc = bdb_id2entry_add( be, tid, e );
       if( rc != 0 ) {
              snprintf( text->bv_val, text->bv_len,
                            "id2entry_add failed: %s (%d)",
                            db_strerror(rc), rc );
              Debug( LDAP_DEBUG_ANY,
                     "=> " LDAP_XSTRING(bdb_tool_entry_put) ": %s\n",
                     text->bv_val, 0, 0 );
              goto done;
       }

done:
       if( rc == 0 ) {
              if ( !( slapMode & SLAP_TOOL_QUICK )) {
              rc = TXN_COMMIT( tid, 0 );
              if( rc != 0 ) {
                     snprintf( text->bv_val, text->bv_len,
                                   "txn_commit failed: %s (%d)",
                                   db_strerror(rc), rc );
                     Debug( LDAP_DEBUG_ANY,
                            "=> " LDAP_XSTRING(bdb_tool_entry_put) ": %s\n",
                            text->bv_val, 0, 0 );
                     e->e_id = NOID;
              }
              }

       } else {
              if ( !( slapMode & SLAP_TOOL_QUICK )) {
              TXN_ABORT( tid );
              snprintf( text->bv_val, text->bv_len,
                     "txn_aborted! %s (%d)",
                     rc == LDAP_OTHER ? "Internal error" :
                     db_strerror(rc), rc );
              Debug( LDAP_DEBUG_ANY,
                     "=> " LDAP_XSTRING(bdb_tool_entry_put) ": %s\n",
                     text->bv_val, 0, 0 );
              }
              e->e_id = NOID;
       }

       return e->e_id;
}

Here is the call graph for this function:

Definition at line 751 of file tools.c.

{
       struct bdb_info *bi = (struct bdb_info *) be->be_private;
       int rc;
       Entry *e;
       DB_TXN *tid = NULL;
       Operation op = {0};
       Opheader ohdr = {0};

       Debug( LDAP_DEBUG_ARGS,
              "=> " LDAP_XSTRING(bdb_tool_entry_reindex) "( %ld )\n",
              (long) id, 0, 0 );
       assert( tool_base == NULL );
       assert( tool_filter == NULL );

       /* No indexes configured, nothing to do. Could return an
        * error here to shortcut things.
        */
       if (!bi->bi_attrs) {
              return 0;
       }

       /* Check for explicit list of attrs to index */
       if ( adv ) {
              int i, j, n;

              if ( bi->bi_attrs[0]->ai_desc != adv[0] ) {
                     /* count */
                     for ( n = 0; adv[n]; n++ ) ;

                     /* insertion sort */
                     for ( i = 0; i < n; i++ ) {
                            AttributeDescription *ad = adv[i];
                            for ( j = i-1; j>=0; j--) {
                                   if ( SLAP_PTRCMP( adv[j], ad ) <= 0 ) break;
                                   adv[j+1] = adv[j];
                            }
                            adv[j+1] = ad;
                     }
              }

              for ( i = 0; adv[i]; i++ ) {
                     if ( bi->bi_attrs[i]->ai_desc != adv[i] ) {
                            for ( j = i+1; j < bi->bi_nattrs; j++ ) {
                                   if ( bi->bi_attrs[j]->ai_desc == adv[i] ) {
                                          AttrInfo *ai = bi->bi_attrs[i];
                                          bi->bi_attrs[i] = bi->bi_attrs[j];
                                          bi->bi_attrs[j] = ai;
                                          break;
                                   }
                            }
                            if ( j == bi->bi_nattrs ) {
                                   Debug( LDAP_DEBUG_ANY,
                                          LDAP_XSTRING(bdb_tool_entry_reindex)
                                          ": no index configured for %s\n",
                                          adv[i]->ad_cname.bv_val, 0, 0 );
                                   return -1;
                            }
                     }
              }
              bi->bi_nattrs = i;
       }

       /* Get the first attribute to index */
       if (bi->bi_linear_index && !index_nattrs) {
              index_nattrs = bi->bi_nattrs - 1;
              bi->bi_nattrs = 1;
       }

       e = bdb_tool_entry_get( be, id );

       if( e == NULL ) {
              Debug( LDAP_DEBUG_ANY,
                     LDAP_XSTRING(bdb_tool_entry_reindex)
                     ": could not locate id=%ld\n",
                     (long) id, 0, 0 );
              return -1;
       }

       if (! (slapMode & SLAP_TOOL_QUICK)) {
       rc = TXN_BEGIN( bi->bi_dbenv, NULL, &tid, bi->bi_db_opflags );
       if( rc != 0 ) {
              Debug( LDAP_DEBUG_ANY,
                     "=> " LDAP_XSTRING(bdb_tool_entry_reindex) ": "
                     "txn_begin failed: %s (%d)\n",
                     db_strerror(rc), rc, 0 );
              goto done;
       }
       }
       
       /*
        * just (re)add them for now
        * assume that some other routine (not yet implemented)
        * will zap index databases
        *
        */

       Debug( LDAP_DEBUG_TRACE,
              "=> " LDAP_XSTRING(bdb_tool_entry_reindex) "( %ld, \"%s\" )\n",
              (long) id, e->e_dn, 0 );

       op.o_hdr = &ohdr;
       op.o_bd = be;
       op.o_tmpmemctx = NULL;
       op.o_tmpmfuncs = &ch_mfuncs;

       rc = bdb_tool_index_add( &op, tid, e );

done:
       if( rc == 0 ) {
              if (! (slapMode & SLAP_TOOL_QUICK)) {
              rc = TXN_COMMIT( tid, 0 );
              if( rc != 0 ) {
                     Debug( LDAP_DEBUG_ANY,
                            "=> " LDAP_XSTRING(bdb_tool_entry_reindex)
                            ": txn_commit failed: %s (%d)\n",
                            db_strerror(rc), rc, 0 );
                     e->e_id = NOID;
              }
              }

       } else {
              if (! (slapMode & SLAP_TOOL_QUICK)) {
              TXN_ABORT( tid );
              Debug( LDAP_DEBUG_ANY,
                     "=> " LDAP_XSTRING(bdb_tool_entry_reindex)
                     ": txn_aborted! %s (%d)\n",
                     db_strerror(rc), rc, 0 );
              }
              e->e_id = NOID;
       }
       bdb_entry_release( &op, e, 0 );

       return rc;
}
static int bdb_tool_index_add ( Operation op,
DB_TXN *  txn,
Entry e 
) [static]

Definition at line 580 of file tools.c.

{
       struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;

       if ( !bdb->bi_nattrs )
              return 0;

       if ( bdb_tool_threads > 1 ) {
              IndexRec *ir;
              int i, rc;
              Attribute *a;
              
              ir = bdb_tool_index_rec;
              memset(ir, 0, bdb->bi_nattrs * sizeof( IndexRec ));

              for ( a = e->e_attrs; a != NULL; a = a->a_next ) {
                     rc = bdb_index_recset( bdb, a, a->a_desc->ad_type, 
                            &a->a_desc->ad_tags, ir );
                     if ( rc )
                            return rc;
              }
              bdb_tool_ix_id = e->e_id;
              bdb_tool_ix_op = op;
              ldap_pvt_thread_mutex_lock( &bdb_tool_index_mutex );
              /* Wait for all threads to be ready */
              while ( bdb_tool_index_tcount > 0 ) {
                     ldap_pvt_thread_cond_wait( &bdb_tool_index_cond_main, 
                            &bdb_tool_index_mutex );
              }
              for ( i=1; i<bdb_tool_threads; i++ )
                     bdb_tool_index_threads[i] = LDAP_BUSY;
              bdb_tool_index_tcount = bdb_tool_threads - 1;
              ldap_pvt_thread_cond_broadcast( &bdb_tool_index_cond_work );
              ldap_pvt_thread_mutex_unlock( &bdb_tool_index_mutex );
              rc = bdb_index_recrun( op, bdb, ir, e->e_id, 0 );
              if ( rc )
                     return rc;
              ldap_pvt_thread_mutex_lock( &bdb_tool_index_mutex );
              for ( i=1; i<bdb_tool_threads; i++ ) {
                     if ( bdb_tool_index_threads[i] == LDAP_BUSY ) {
                            ldap_pvt_thread_cond_wait( &bdb_tool_index_cond_main, 
                                   &bdb_tool_index_mutex );
                            i--;
                            continue;
                     }
                     if ( bdb_tool_index_threads[i] ) {
                            rc = bdb_tool_index_threads[i];
                            break;
                     }
              }
              ldap_pvt_thread_mutex_unlock( &bdb_tool_index_mutex );
              return rc;
       } else {
              return bdb_index_entry_add( op, txn, e );
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void * bdb_tool_index_task ( void ctx,
void ptr 
) [static]

Definition at line 1295 of file tools.c.

{
       int base = *(int *)ptr;

       free( ptr );
       while ( 1 ) {
              ldap_pvt_thread_mutex_lock( &bdb_tool_index_mutex );
              bdb_tool_index_tcount--;
              if ( !bdb_tool_index_tcount )
                     ldap_pvt_thread_cond_signal( &bdb_tool_index_cond_main );
              ldap_pvt_thread_cond_wait( &bdb_tool_index_cond_work,
                     &bdb_tool_index_mutex );
              if ( slapd_shutdown ) {
                     bdb_tool_index_tcount--;
                     if ( !bdb_tool_index_tcount )
                            ldap_pvt_thread_cond_signal( &bdb_tool_index_cond_main );
                     ldap_pvt_thread_mutex_unlock( &bdb_tool_index_mutex );
                     break;
              }
              ldap_pvt_thread_mutex_unlock( &bdb_tool_index_mutex );

              bdb_tool_index_threads[base] = bdb_index_recrun( bdb_tool_ix_op,
                     bdb_tool_info, bdb_tool_index_rec, bdb_tool_ix_id, base );
       }

       return NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int bdb_tool_next_id ( Operation op,
DB_TXN *  tid,
Entry e,
struct berval text,
int  hole 
) [static]

Definition at line 488 of file tools.c.

{
       struct berval dn = e->e_name;
       struct berval ndn = e->e_nname;
       struct berval pdn, npdn;
       EntryInfo *ei = NULL, eidummy;
       int rc;

       if (ndn.bv_len == 0) {
              e->e_id = 0;
              return 0;
       }

       rc = bdb_cache_find_ndn( op, tid, &ndn, &ei );
       if ( ei ) bdb_cache_entryinfo_unlock( ei );
       if ( rc == DB_NOTFOUND ) {
              if ( !be_issuffix( op->o_bd, &ndn ) ) {
                     ID eid = e->e_id;
                     dnParent( &dn, &pdn );
                     dnParent( &ndn, &npdn );
                     e->e_name = pdn;
                     e->e_nname = npdn;
                     rc = bdb_tool_next_id( op, tid, e, text, 1 );
                     e->e_name = dn;
                     e->e_nname = ndn;
                     if ( rc ) {
                            return rc;
                     }
                     /* If parent didn't exist, it was created just now
                      * and its ID is now in e->e_id. Make sure the current
                      * entry gets added under the new parent ID.
                      */
                     if ( eid != e->e_id ) {
                            eidummy.bei_id = e->e_id;
                            ei = &eidummy;
                     }
              }
              rc = bdb_next_id( op->o_bd, &e->e_id );
              if ( rc ) {
                     snprintf( text->bv_val, text->bv_len,
                            "next_id failed: %s (%d)",
                            db_strerror(rc), rc );
              Debug( LDAP_DEBUG_ANY,
                     "=> bdb_tool_next_id: %s\n", text->bv_val, 0, 0 );
                     return rc;
              }
              rc = bdb_dn2id_add( op, tid, ei, e );
              if ( rc ) {
                     snprintf( text->bv_val, text->bv_len, 
                            "dn2id_add failed: %s (%d)",
                            db_strerror(rc), rc );
              Debug( LDAP_DEBUG_ANY,
                     "=> bdb_tool_next_id: %s\n", text->bv_val, 0, 0 );
              } else if ( hole ) {
                     if ( nholes == nhmax - 1 ) {
                            if ( holes == hbuf ) {
                                   holes = ch_malloc( nhmax * sizeof(dn_id) * 2 );
                                   AC_MEMCPY( holes, hbuf, sizeof(hbuf) );
                            } else {
                                   holes = ch_realloc( holes, nhmax * sizeof(dn_id) * 2 );
                            }
                            nhmax *= 2;
                     }
                     ber_dupbv( &holes[nholes].dn, &ndn );
                     holes[nholes++].id = e->e_id;
              }
       } else if ( !hole ) {
              unsigned i, j;

              e->e_id = ei->bei_id;

              for ( i=0; i<nholes; i++) {
                     if ( holes[i].id == e->e_id ) {
                            free(holes[i].dn.bv_val);
                            for (j=i;j<nholes;j++) holes[j] = holes[j+1];
                            holes[j].id = 0;
                            nholes--;
                            break;
                     } else if ( holes[i].id > e->e_id ) {
                            break;
                     }
              }
       }
       return rc;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

Definition at line 80 of file tools.c.

Definition at line 81 of file tools.c.

Definition at line 79 of file tools.c.

Definition at line 77 of file tools.c.

Definition at line 76 of file tools.c.

Definition at line 76 of file tools.c.

struct bdb_info* bdb_tool_info [static]

Definition at line 78 of file tools.c.

ID bdb_tool_ix_id [static]

Definition at line 74 of file tools.c.

Definition at line 75 of file tools.c.

Definition at line 104 of file tools.c.

DBC* cursor = NULL [static]

Definition at line 27 of file tools.c.

DBT data [static]

Definition at line 28 of file tools.c.

EntryHeader eh [static]

Definition at line 29 of file tools.c.

char ehbuf[16] [static]

Definition at line 31 of file tools.c.

dn_id hbuf[HOLE_SIZE] [static]

Definition at line 39 of file tools.c.

dn_id * holes = hbuf [static]

Definition at line 39 of file tools.c.

int index_nattrs [static]

Definition at line 43 of file tools.c.

DBT key [static]

Definition at line 28 of file tools.c.

unsigned nhmax = HOLE_SIZE [static]

Definition at line 40 of file tools.c.

unsigned nholes [static]

Definition at line 41 of file tools.c.

ID nid [static]

Definition at line 30 of file tools.c.

ID previd = NOID [static]

Definition at line 30 of file tools.c.

struct berval* tool_base [static]

Definition at line 45 of file tools.c.

Filter* tool_filter [static]

Definition at line 47 of file tools.c.

Definition at line 48 of file tools.c.

int tool_scope [static]

Definition at line 46 of file tools.c.