Beispiel #1
0
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;
}
Beispiel #2
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;
}
Beispiel #3
0
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;
}
Beispiel #4
0
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;
}