From: Ondřej Kuzník Date: Tue, 11 Aug 2015 12:31:35 +0000 (+0200) Subject: ITS#8215 Add mdb tool delete support X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=085eb2e8df7f6650bd8b911d08399b48ff3de4ef;p=openldap ITS#8215 Add mdb tool delete support --- diff --git a/servers/slapd/back-mdb/init.c b/servers/slapd/back-mdb/init.c index 1089e0f01c..57dc46a39c 100644 --- a/servers/slapd/back-mdb/init.c +++ b/servers/slapd/back-mdb/init.c @@ -482,6 +482,7 @@ mdb_back_initialize( bi->bi_tool_sync = 0; bi->bi_tool_dn2id_get = mdb_tool_dn2id_get; bi->bi_tool_entry_modify = mdb_tool_entry_modify; + bi->bi_tool_entry_delete = mdb_tool_entry_delete; bi->bi_connection_init = 0; bi->bi_connection_destroy = 0; diff --git a/servers/slapd/back-mdb/proto-mdb.h b/servers/slapd/back-mdb/proto-mdb.h index abafa85cdb..c475e0b15e 100644 --- a/servers/slapd/back-mdb/proto-mdb.h +++ b/servers/slapd/back-mdb/proto-mdb.h @@ -386,6 +386,7 @@ extern BI_tool_entry_put mdb_tool_entry_put; extern BI_tool_entry_reindex mdb_tool_entry_reindex; extern BI_tool_dn2id_get mdb_tool_dn2id_get; extern BI_tool_entry_modify mdb_tool_entry_modify; +extern BI_tool_entry_delete mdb_tool_entry_delete; extern mdb_idl_keyfunc mdb_tool_idl_add; diff --git a/servers/slapd/back-mdb/tools.c b/servers/slapd/back-mdb/tools.c index f0392ecb81..c805444063 100644 --- a/servers/slapd/back-mdb/tools.c +++ b/servers/slapd/back-mdb/tools.c @@ -1035,11 +1035,169 @@ done: 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 ) {