/* $OpenLDAP$ */
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
*
- * Copyright 2011-2014 The OpenLDAP Foundation.
+ * Copyright 2011-2017 The OpenLDAP Foundation.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
slapd_shutdown = 0;
ch_free( mdb_tool_index_rec );
mdb_tool_index_tcount = mdb_tool_threads - 1;
- if (txn)
- MDB_TOOL_IDL_FLUSH( be, txn );
+ if (mdb_tool_txn)
+ MDB_TOOL_IDL_FLUSH( be, mdb_tool_txn );
for (i=0; i<mdb_tool_threads; i++) {
mdb_tool_idl_cache *ic;
mdb_tool_idl_cache_entry *ice;
mdb_cursor_close( cursor );
cursor = NULL;
}
+ {
+ struct mdb_info *mdb = be->be_private;
+ if ( mdb ) {
+ int i;
+ for (i=0; i<mdb->mi_nattrs; i++)
+ mdb->mi_attrs[i]->ai_cursor = NULL;
+ }
+ }
if( mdb_tool_txn ) {
int rc;
if (( rc = mdb_txn_commit( mdb_tool_txn ))) {
rc = mdb_id2name( &op, mdb_tool_txn, &idcursor, id, &dn, &ndn );
if ( rc ) {
rc = LDAP_OTHER;
- if ( e ) {
- mdb_entry_return( &op, e );
- e = NULL;
- }
goto done;
}
if ( tool_base != NULL ) {
}
}
}
- rc = mdb_entry_decode( &op, mdb_tool_txn, &data, &e );
+ rc = mdb_entry_decode( &op, mdb_tool_txn, &data, id, &e );
e->e_id = id;
if ( !BER_BVISNULL( &dn )) {
e->e_name = dn;
struct berval *text,
int hole )
{
- struct mdb_info *mdb = (struct mdb_info *) op->o_bd->be_private;
struct berval dn = e->e_name;
struct berval ndn = e->e_nname;
struct berval pdn, npdn, nmatched;
static int
mdb_tool_index_finish()
{
- int i, rc;
+ int i, rc = 0;
ldap_pvt_thread_mutex_lock( &mdb_tool_index_mutex );
for ( i=1; i<mdb_tool_threads; i++ ) {
if ( mdb_tool_index_rec[i].ir_i == LDAP_BUSY ) {
mdb_tool_txn = NULL;
idcursor = NULL;
if( rc != 0 ) {
+ mdb->mi_numads = 0;
snprintf( text->bv_val, text->bv_len,
"txn_commit failed: %s (%d)",
mdb_strerror(rc), rc );
if( rc == 0 ) {
rc = mdb_txn_commit( mdb_tool_txn );
if( rc != 0 ) {
+ mdb->mi_numads = 0;
snprintf( text->bv_val, text->bv_len,
"txn_commit failed: %s (%d)",
mdb_strerror(rc), rc );
e->e_id = NOID;
}
mdb_tool_txn = NULL;
- idcursor = NULL;
return e->e_id;
}
+int mdb_tool_entry_delete(
+ BackendDB *be,
+ struct berval *ndn,
+ struct berval *text )
+{
+ int rc;
+ struct mdb_info *mdb;
+ Operation op = {0};
+ Opheader ohdr = {0};
+ Entry *e;
+
+ assert( be != NULL );
+ assert( slapMode & SLAP_TOOL_MODE );
+
+ assert( text != NULL );
+ assert( text->bv_val != NULL );
+ assert( text->bv_val[0] == '\0' ); /* overconservative? */
+
+ assert ( ndn != NULL );
+ assert ( ndn->bv_val != NULL );
+
+ Debug( LDAP_DEBUG_TRACE,
+ "=> " LDAP_XSTRING(mdb_tool_entry_delete) "( %s )\n",
+ ndn->bv_val, 0, 0 );
+
+ mdb = (struct mdb_info *) be->be_private;
+
+ assert( cursor == NULL );
+ if( cursor ) {
+ mdb_cursor_close( cursor );
+ cursor = NULL;
+ }
+ if( !mdb_tool_txn ) {
+ rc = mdb_txn_begin( mdb->mi_dbenv, NULL, 0, &mdb_tool_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_delete) ": %s\n",
+ text->bv_val, 0, 0 );
+ return LDAP_OTHER;
+ }
+ }
+
+ rc = mdb_cursor_open( mdb_tool_txn, mdb->mi_dn2id, &cursor );
+ 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_delete) ": %s\n",
+ text->bv_val, 0, 0 );
+ return LDAP_OTHER;
+ }
+
+ op.o_hdr = &ohdr;
+ op.o_bd = be;
+ op.o_tmpmemctx = NULL;
+ op.o_tmpmfuncs = &ch_mfuncs;
+
+ rc = mdb_dn2entry( &op, mdb_tool_txn, cursor, ndn, &e, NULL, 0 );
+ if( rc != 0 ) {
+ snprintf( text->bv_val, text->bv_len,
+ "dn2entry failed: %s (%d)",
+ mdb_strerror(rc), rc );
+ Debug( LDAP_DEBUG_ANY,
+ "=> " LDAP_XSTRING(mdb_tool_entry_delete) ": %s\n",
+ text->bv_val, 0, 0 );
+ goto done;
+ }
+
+ /* check that we wouldn't orphan any children */
+ rc = mdb_dn2id_children( &op, mdb_tool_txn, e );
+ if( rc != MDB_NOTFOUND ) {
+ switch( rc ) {
+ case 0:
+ snprintf( text->bv_val, text->bv_len,
+ "delete failed:"
+ " subordinate objects must be deleted first");
+ break;
+ default:
+ snprintf( text->bv_val, text->bv_len,
+ "has_children failed: %s (%d)",
+ mdb_strerror(rc), rc );
+ break;
+ }
+ rc = -1;
+ Debug( LDAP_DEBUG_ANY,
+ "=> " LDAP_XSTRING(mdb_tool_entry_delete) ": %s\n",
+ text->bv_val, 0, 0 );
+ goto done;
+ }
+
+ /* delete from dn2id */
+ rc = mdb_dn2id_delete( &op, cursor, e->e_id, 1 );
+ if( rc != 0 ) {
+ snprintf( text->bv_val, text->bv_len,
+ "dn2id_delete failed: err=%d", rc );
+ Debug( LDAP_DEBUG_ANY,
+ "=> " LDAP_XSTRING(mdb_tool_entry_delete) ": %s\n",
+ text->bv_val, 0, 0 );
+ goto done;
+ }
+
+ /* deindex values */
+ rc = mdb_index_entry_del( &op, mdb_tool_txn, e );
+ if( rc != 0 ) {
+ snprintf( text->bv_val, text->bv_len,
+ "entry_delete failed: err=%d", rc );
+ Debug( LDAP_DEBUG_ANY,
+ "=> " LDAP_XSTRING(mdb_tool_entry_delete) ": %s\n",
+ text->bv_val, 0, 0 );
+ goto done;
+ }
+
+ /* do the deletion */
+ rc = mdb_id2entry_delete( be, mdb_tool_txn, e );
+ if( rc != 0 ) {
+ snprintf( text->bv_val, text->bv_len,
+ "id2entry_update failed: err=%d", rc );
+ Debug( LDAP_DEBUG_ANY,
+ "=> " LDAP_XSTRING(mdb_tool_entry_delete) ": %s\n",
+ text->bv_val, 0, 0 );
+ goto done;
+ }
+
+done:
+ /* free entry */
+ if( e != NULL ) {
+ mdb_entry_return( &op, e );
+ }
+
+ if( rc == 0 ) {
+ rc = mdb_txn_commit( mdb_tool_txn );
+ 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_delete) ": "
+ "%s\n", text->bv_val, 0, 0 );
+ }
+
+ } else {
+ mdb_txn_abort( mdb_tool_txn );
+ snprintf( text->bv_val, text->bv_len,
+ "txn_aborted! %s (%d)",
+ mdb_strerror(rc), rc );
+ Debug( LDAP_DEBUG_ANY,
+ "=> " LDAP_XSTRING(mdb_tool_entry_delete) ": %s\n",
+ text->bv_val, 0, 0 );
+ }
+ mdb_tool_txn = NULL;
+ cursor = NULL;
+
+ return rc;
+}
+
static void *
mdb_tool_index_task( void *ctx, void *ptr )
{
dbi = ai->ai_dbi;
for (i=0; keys[i].bv_val; i++) {
itmp.kstr = keys[i];
- ic = tavl_find( (Avlnode *)ai->ai_root, &itmp, mdb_tool_idl_cmp );
+ ic = tavl_find( ai->ai_root, &itmp, mdb_tool_idl_cmp );
/* No entry yet, create one */
if ( !ic ) {
ic->count = 0;
ic->offset = 0;
ic->flags = 0;
- tavl_insert( (Avlnode **)&ai->ai_root, ic, mdb_tool_idl_cmp,
+ tavl_insert( &ai->ai_root, ic, mdb_tool_idl_cmp,
avl_dup_error );
/* load existing key count here */
MDB_txn *mt;
MDB_cursor *mc = NULL;
MDB_val key, data;
- char *ptr;
int rc, writes=0, depth=0;
int enable_meter = 0;
ID id = 0, *num, count = 0;