From: Ondřej Kuzník Date: Tue, 11 Aug 2015 12:31:22 +0000 (+0200) Subject: ITS#8215 Add bdb tool delete support X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=f3e8aa5849d21befc499b2f8eda113f3207d6f4b;p=openldap ITS#8215 Add bdb tool delete support --- diff --git a/servers/slapd/back-bdb/init.c b/servers/slapd/back-bdb/init.c index 9d031a5025..02a6407f48 100644 --- a/servers/slapd/back-bdb/init.c +++ b/servers/slapd/back-bdb/init.c @@ -851,6 +851,7 @@ bdb_back_initialize( bi->bi_tool_sync = 0; bi->bi_tool_dn2id_get = bdb_tool_dn2id_get; bi->bi_tool_entry_modify = bdb_tool_entry_modify; + bi->bi_tool_entry_delete = bdb_tool_entry_delete; bi->bi_connection_init = 0; bi->bi_connection_destroy = 0; diff --git a/servers/slapd/back-bdb/proto-bdb.h b/servers/slapd/back-bdb/proto-bdb.h index 8466b96420..f075120276 100644 --- a/servers/slapd/back-bdb/proto-bdb.h +++ b/servers/slapd/back-bdb/proto-bdb.h @@ -640,6 +640,7 @@ bdb_trans_backoff( int num_retries ); #define bdb_tool_dn2id_get BDB_SYMBOL(tool_dn2id_get) #define bdb_tool_entry_modify BDB_SYMBOL(tool_entry_modify) #define bdb_tool_idl_add BDB_SYMBOL(tool_idl_add) +#define bdb_tool_entry_delete BDB_SYMBOL(tool_entry_delete) extern BI_init bdb_back_initialize; @@ -670,6 +671,7 @@ extern BI_tool_entry_put bdb_tool_entry_put; extern BI_tool_entry_reindex bdb_tool_entry_reindex; extern BI_tool_dn2id_get bdb_tool_dn2id_get; extern BI_tool_entry_modify bdb_tool_entry_modify; +extern BI_tool_entry_delete bdb_tool_entry_delete; int bdb_tool_idl_add( BackendDB *be, DB *db, DB_TXN *txn, DBT *key, ID id ); diff --git a/servers/slapd/back-bdb/tools.c b/servers/slapd/back-bdb/tools.c index 8f566132a2..1ec1053dfd 100644 --- a/servers/slapd/back-bdb/tools.c +++ b/servers/slapd/back-bdb/tools.c @@ -1003,6 +1003,168 @@ done: return e->e_id; } +int bdb_tool_entry_delete( + BackendDB *be, + struct berval *ndn, + struct berval *text ) +{ + int rc; + struct bdb_info *bdb; + DB_TXN *tid = NULL; + Operation op = {0}; + Opheader ohdr = {0}; + EntryInfo *ei, *eip; + Entry *e; + DB_LOCK lock; + + 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(bdb_tool_entry_delete) "( %s )\n", + ndn->bv_val, 0, 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_delete) ": %s\n", + text->bv_val, 0, 0 ); + return LDAP_OTHER; + } + rc = bdb->bi_id2entry->bdi_db->cursor( + bdb->bi_id2entry->bdi_db, bdb->bi_cache.c_txn, &cursor, + bdb->bi_db_opflags ); + } + + op.o_hdr = &ohdr; + op.o_bd = be; + op.o_tmpmemctx = NULL; + op.o_tmpmfuncs = &ch_mfuncs; + + /* do the deletion */ + rc = bdb_dn2entry( &op, tid, ndn, &ei, 1, &lock ); + if( rc != 0 ) { + snprintf( text->bv_val, text->bv_len, + "dn2entry failed: %s (%d)", + db_strerror(rc), rc ); + Debug( LDAP_DEBUG_ANY, + "=> " LDAP_XSTRING(bdb_tool_entry_delete) ": %s\n", + text->bv_val, 0, 0 ); + goto done; + } + + e = ei->bei_e; + eip = ei->bei_parent; + + rc = bdb_cache_children( &op, tid, e ); + if( rc != DB_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)", + db_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; + } + rc = bdb_dn2id_delete( &op, tid, eip, e ); + if( rc != 0 ) { + snprintf( text->bv_val, text->bv_len, + "dn2entry failed: %s (%d)", + db_strerror(rc), rc ); + Debug( LDAP_DEBUG_ANY, + "=> " LDAP_XSTRING(bdb_tool_entry_delete) ": %s\n", + text->bv_val, 0, 0 ); + goto done; + } + + rc = bdb_index_entry_del( &op, tid, e ); + if( rc != 0 ) { + snprintf( text->bv_val, text->bv_len, + "dn2entry failed: %s (%d)", + db_strerror(rc), rc ); + Debug( LDAP_DEBUG_ANY, + "=> " LDAP_XSTRING(bdb_tool_entry_delete) ": %s\n", + text->bv_val, 0, 0 ); + goto done; + } + + rc = bdb_id2entry_delete( be, tid, e ); + if( rc != 0 ) { + snprintf( text->bv_val, text->bv_len, + "dn2entry failed: %s (%d)", + db_strerror(rc), rc ); + Debug( LDAP_DEBUG_ANY, + "=> " LDAP_XSTRING(bdb_tool_entry_delete) ": %s\n", + text->bv_val, 0, 0 ); + goto done; + } + +done: + /* Free the EntryInfo and the Entry */ + if( e != NULL ) { + bdb_entry_release( &op, e, 0 ); + } + + 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_delete) ": " + "%s\n", text->bv_val, 0, 0 ); + } + } + + } 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_delete) ": %s\n", + text->bv_val, 0, 0 ); + } + } + + rc = bdb->bi_id2entry->bdi_db->cursor( + bdb->bi_id2entry->bdi_db, bdb->bi_cache.c_txn, &cursor, + bdb->bi_db_opflags ); + + return rc; +} + #ifdef BDB_TOOL_IDL_CACHING static int bdb_tool_idl_cmp( const void *v1, const void *v2 )