int mdb_tool_entry_close( BackendDB *be ) { if ( mdb_tool_info ) { slapd_shutdown = 1; ldap_pvt_thread_mutex_lock( &mdb_tool_index_mutex ); /* There might still be some threads starting */ while ( mdb_tool_index_tcount > 0 ) { ldap_pvt_thread_cond_wait( &mdb_tool_index_cond_main, &mdb_tool_index_mutex ); } mdb_tool_index_tcount = mdb_tool_threads - 1; ldap_pvt_thread_cond_broadcast( &mdb_tool_index_cond_work ); /* Make sure all threads are stopped */ while ( mdb_tool_index_tcount > 0 ) { ldap_pvt_thread_cond_wait( &mdb_tool_index_cond_main, &mdb_tool_index_mutex ); } ldap_pvt_thread_mutex_unlock( &mdb_tool_index_mutex ); mdb_tool_info = NULL; slapd_shutdown = 0; ch_free( mdb_tool_index_rec ); mdb_tool_index_tcount = mdb_tool_threads - 1; } if( idcursor ) { mdb_cursor_close( idcursor ); idcursor = NULL; } if( cursor ) { mdb_cursor_close( cursor ); cursor = NULL; } if( txn ) { MDB_TOOL_IDL_FLUSH( be, txn ); if ( mdb_txn_commit( txn )) return -1; txn = NULL; } 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); } nholes = 0; return -1; } return 0; }
int mdb_tool_entry_reindex( BackendDB *be, ID id, AttributeDescription **adv ) { struct mdb_info *mi = (struct mdb_info *) be->be_private; int rc; Entry *e; Operation op = {0}; Opheader ohdr = {0}; Debug( LDAP_DEBUG_ARGS, "=> " LDAP_XSTRING(mdb_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 (!mi->mi_attrs) { return 0; } /* Check for explicit list of attrs to index */ if ( adv ) { int i, j, n; if ( mi->mi_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 ( mi->mi_attrs[i]->ai_desc != adv[i] ) { for ( j = i+1; j < mi->mi_nattrs; j++ ) { if ( mi->mi_attrs[j]->ai_desc == adv[i] ) { AttrInfo *ai = mi->mi_attrs[i]; mi->mi_attrs[i] = mi->mi_attrs[j]; mi->mi_attrs[j] = ai; break; } } if ( j == mi->mi_nattrs ) { Debug( LDAP_DEBUG_ANY, LDAP_XSTRING(mdb_tool_entry_reindex) ": no index configured for %s\n", adv[i]->ad_cname.bv_val, 0, 0 ); return -1; } } } mi->mi_nattrs = i; } e = mdb_tool_entry_get( be, id ); if( e == NULL ) { Debug( LDAP_DEBUG_ANY, LDAP_XSTRING(mdb_tool_entry_reindex) ": could not locate id=%ld\n", (long) id, 0, 0 ); return -1; } if ( !txi ) { rc = mdb_txn_begin( mi->mi_dbenv, NULL, 0, &txi ); if( rc != 0 ) { Debug( LDAP_DEBUG_ANY, "=> " LDAP_XSTRING(mdb_tool_entry_reindex) ": " "txn_begin failed: %s (%d)\n", mdb_strerror(rc), rc, 0 ); goto done; } } if ( slapMode & SLAP_TRUNCATE_MODE ) { int i; for ( i=0; i < mi->mi_nattrs; i++ ) { rc = mdb_drop( txi, mi->mi_attrs[i]->ai_dbi, 0 ); if ( rc ) { Debug( LDAP_DEBUG_ANY, LDAP_XSTRING(mdb_tool_entry_reindex) ": (Truncate) mdb_drop(%s) failed: %s (%d)\n", mi->mi_attrs[i]->ai_desc->ad_type->sat_cname.bv_val, mdb_strerror(rc), rc ); return -1; } } slapMode ^= SLAP_TRUNCATE_MODE; } /* * just (re)add them for now * Use truncate mode to empty/reset index databases */ Debug( LDAP_DEBUG_TRACE, "=> " LDAP_XSTRING(mdb_tool_entry_reindex) "( %ld )\n", (long) id, 0, 0 ); op.o_hdr = &ohdr; op.o_bd = be; op.o_tmpmemctx = NULL; op.o_tmpmfuncs = &ch_mfuncs; rc = mdb_tool_index_add( &op, txi, e ); done: if( rc == 0 ) { mdb_writes++; if ( mdb_writes >= mdb_writes_per_commit ) { unsigned i; MDB_TOOL_IDL_FLUSH( be, txi ); rc = mdb_txn_commit( txi ); mdb_writes = 0; for ( i=0; i<mi->mi_nattrs; i++ ) mi->mi_attrs[i]->ai_cursor = NULL; if( rc != 0 ) { Debug( LDAP_DEBUG_ANY, "=> " LDAP_XSTRING(mdb_tool_entry_reindex) ": txn_commit failed: %s (%d)\n", mdb_strerror(rc), rc, 0 ); e->e_id = NOID; } txi = NULL; } } else { unsigned i; mdb_writes = 0; mdb_txn_abort( txi ); for ( i=0; i<mi->mi_nattrs; i++ ) mi->mi_attrs[i]->ai_cursor = NULL; Debug( LDAP_DEBUG_ANY, "=> " LDAP_XSTRING(mdb_tool_entry_reindex) ": txn_aborted! err=%d\n", rc, 0, 0 ); e->e_id = NOID; txi = NULL; } mdb_entry_release( &op, e, 0 ); return rc; }
ID mdb_tool_entry_put( BackendDB *be, Entry *e, struct berval *text ) { int rc; struct mdb_info *mdb; 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(mdb_tool_entry_put) "( %ld, \"%s\" )\n", (long) e->e_id, e->e_dn, 0 ); mdb = (struct mdb_info *) be->be_private; if ( !txn ) { rc = mdb_txn_begin( mdb->mi_dbenv, NULL, 0, &txn ); if( rc != 0 ) { snprintf( text->bv_val, text->bv_len, "txn_begin failed: %s (%d)", mdb_strerror(rc), rc ); Debug( LDAP_DEBUG_ANY, "=> " LDAP_XSTRING(mdb_tool_entry_put) ": %s\n", text->bv_val, 0, 0 ); return NOID; } rc = mdb_cursor_open( txn, mdb->mi_id2entry, &idcursor ); if( rc != 0 ) { snprintf( text->bv_val, text->bv_len, "cursor_open failed: %s (%d)", mdb_strerror(rc), rc ); Debug( LDAP_DEBUG_ANY, "=> " LDAP_XSTRING(mdb_tool_entry_put) ": %s\n", text->bv_val, 0, 0 ); return NOID; } if ( !mdb->mi_nextid ) { ID dummy; mdb_next_id( be, idcursor, &dummy ); } rc = mdb_cursor_open( txn, mdb->mi_dn2id, &mcp ); if( rc != 0 ) { snprintf( text->bv_val, text->bv_len, "cursor_open failed: %s (%d)", mdb_strerror(rc), rc ); Debug( LDAP_DEBUG_ANY, "=> " LDAP_XSTRING(mdb_tool_entry_put) ": %s\n", text->bv_val, 0, 0 ); return NOID; } rc = mdb_cursor_open( txn, mdb->mi_dn2id, &mcd ); if( rc != 0 ) { snprintf( text->bv_val, text->bv_len, "cursor_open failed: %s (%d)", mdb_strerror(rc), rc ); Debug( LDAP_DEBUG_ANY, "=> " LDAP_XSTRING(mdb_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 = mdb_tool_next_id( &op, txn, e, text, 0 ); if( rc != 0 ) { goto done; } rc = mdb_tool_index_add( &op, txn, e ); if( rc != 0 ) { snprintf( text->bv_val, text->bv_len, "index_entry_add failed: err=%d", rc ); Debug( LDAP_DEBUG_ANY, "=> " LDAP_XSTRING(mdb_tool_entry_put) ": %s\n", text->bv_val, 0, 0 ); goto done; } /* id2entry index */ rc = mdb_id2entry_add( &op, txn, idcursor, e ); if( rc != 0 ) { snprintf( text->bv_val, text->bv_len, "id2entry_add failed: err=%d", rc ); Debug( LDAP_DEBUG_ANY, "=> " LDAP_XSTRING(mdb_tool_entry_put) ": %s\n", text->bv_val, 0, 0 ); goto done; } done: if( rc == 0 ) { mdb_writes++; if ( mdb_writes >= mdb_writes_per_commit ) { unsigned i; MDB_TOOL_IDL_FLUSH( be, txn ); rc = mdb_txn_commit( txn ); for ( i=0; i<mdb->mi_nattrs; i++ ) mdb->mi_attrs[i]->ai_cursor = NULL; mdb_writes = 0; txn = NULL; idcursor = NULL; if( rc != 0 ) { snprintf( text->bv_val, text->bv_len, "txn_commit failed: %s (%d)", mdb_strerror(rc), rc ); Debug( LDAP_DEBUG_ANY, "=> " LDAP_XSTRING(mdb_tool_entry_put) ": %s\n", text->bv_val, 0, 0 ); e->e_id = NOID; } } } else { unsigned i; mdb_txn_abort( txn ); txn = NULL; idcursor = NULL; for ( i=0; i<mdb->mi_nattrs; i++ ) mdb->mi_attrs[i]->ai_cursor = NULL; mdb_writes = 0; snprintf( text->bv_val, text->bv_len, "txn_aborted! %s (%d)", rc == LDAP_OTHER ? "Internal error" : mdb_strerror(rc), rc ); Debug( LDAP_DEBUG_ANY, "=> " LDAP_XSTRING(mdb_tool_entry_put) ": %s\n", text->bv_val, 0, 0 ); e->e_id = NOID; } return e->e_id; }
int mdb_tool_entry_close( BackendDB *be ) { if ( mdb_tool_info ) { slapd_shutdown = 1; ldap_pvt_thread_mutex_lock( &mdb_tool_index_mutex ); /* There might still be some threads starting */ while ( mdb_tool_index_tcount > 0 ) { ldap_pvt_thread_cond_wait( &mdb_tool_index_cond_main, &mdb_tool_index_mutex ); } mdb_tool_index_tcount = mdb_tool_threads - 1; ldap_pvt_thread_cond_broadcast( &mdb_tool_index_cond_work ); /* Make sure all threads are stopped */ while ( mdb_tool_index_tcount > 0 ) { ldap_pvt_thread_cond_wait( &mdb_tool_index_cond_main, &mdb_tool_index_mutex ); } ldap_pvt_thread_mutex_unlock( &mdb_tool_index_mutex ); mdb_tool_info = NULL; slapd_shutdown = 0; ch_free( mdb_tool_index_rec ); mdb_tool_index_tcount = mdb_tool_threads - 1; } if( idcursor ) { mdb_cursor_close( idcursor ); idcursor = NULL; } if( cursor ) { mdb_cursor_close( cursor ); cursor = NULL; } if( mdb_tool_txn ) { int rc; MDB_TOOL_IDL_FLUSH( be, mdb_tool_txn ); if (( rc = mdb_txn_commit( mdb_tool_txn ))) { Debug( LDAP_DEBUG_ANY, LDAP_XSTRING(mdb_tool_entry_close) ": database %s: " "txn_commit failed: %s (%d)\n", be->be_suffix[0].bv_val, mdb_strerror(rc), rc ); return -1; } mdb_tool_txn = NULL; } 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); } nholes = 0; return -1; } return 0; }