]> git.sur5r.net Git - openldap/commitdiff
ITS#8215 Add bdb tool delete support
authorOndřej Kuzník <ondra@mistotebe.net>
Tue, 11 Aug 2015 12:31:22 +0000 (14:31 +0200)
committerHoward Chu <hyc@openldap.org>
Sun, 25 Oct 2015 09:04:00 +0000 (09:04 +0000)
servers/slapd/back-bdb/init.c
servers/slapd/back-bdb/proto-bdb.h
servers/slapd/back-bdb/tools.c

index 9d031a5025a3eb597c05bcd4e543d78c088144a5..02a6407f4826ae3a53522ac28a1b2a90ac4eaece 100644 (file)
@@ -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;
index 8466b96420048f270e3a16491b5016659d4e6bc1..f0751202763b781233f94d3481d9ca4fec471d32 100644 (file)
@@ -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 );
 
index 8f566132a22caa0fd514a6566f892ab3aef91f9f..1ec1053dfdc26f9b3ce0f49b3ec3cabc11f5499c 100644 (file)
@@ -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 )