From 41352ea34da225375b77254efdcde8e6e5a1a515 Mon Sep 17 00:00:00 2001 From: Ralf Haferkamp Date: Fri, 4 Feb 2011 16:10:11 +0000 Subject: [PATCH] Fixed the overlay delete code to allow removing cn=config overlays again. --- servers/slapd/backover.c | 77 +++++++++++++++++++++++++++----------- servers/slapd/bconfig.c | 7 +--- servers/slapd/proto-slap.h | 2 +- 3 files changed, 57 insertions(+), 29 deletions(-) diff --git a/servers/slapd/backover.c b/servers/slapd/backover.c index 327d0130f4..f04171640e 100644 --- a/servers/slapd/backover.c +++ b/servers/slapd/backover.c @@ -1148,39 +1148,72 @@ overlay_destroy_one( BackendDB *be, slap_overinst *on ) } #ifdef SLAP_CONFIG_DELETE +typedef struct ov_remove_ctx { + BackendDB *be; + slap_overinst *on; +} ov_remove_ctx; + +int +overlay_remove_cb( Operation *op, SlapReply *rs ) +{ + ov_remove_ctx *rm_ctx = (ov_remove_ctx*) op->o_callback->sc_private; + BackendInfo *bi_orig = rm_ctx->be->bd_info; + + rm_ctx->be->bd_info = (BackendInfo*) rm_ctx->on; + + if ( rm_ctx->on->on_bi.bi_db_close ) { + rm_ctx->on->on_bi.bi_db_close( rm_ctx->be, NULL ); + } + if ( rm_ctx->on->on_bi.bi_db_destroy ) { + rm_ctx->on->on_bi.bi_db_destroy( rm_ctx->be, NULL ); + } + + /* clean up after removing last overlay */ + if ( ! rm_ctx->on->on_info->oi_list ) { + /* reset db flags and bd_info to orig */ + SLAP_DBFLAGS( rm_ctx->be ) &= ~SLAP_DBFLAG_GLOBAL_OVERLAY; + rm_ctx->be->bd_info = rm_ctx->on->on_info->oi_orig; + ch_free(rm_ctx->on->on_info); + } else { + rm_ctx->be->bd_info = bi_orig; + } + free( rm_ctx->on ); + op->o_tmpfree(rm_ctx, op->o_tmpmemctx); + return SLAP_CB_CONTINUE; +} + void -overlay_remove( BackendDB *be, slap_overinst *on ) +overlay_remove( BackendDB *be, slap_overinst *on, Operation *op ) { slap_overinfo *oi = on->on_info; slap_overinst **oidx; - BackendInfo *bi_orig; + ov_remove_ctx *rm_ctx; + slap_callback *rm_cb, *cb; - /* remove overlay from oi_list an call db_close and db_destroy - * handlers */ + /* remove overlay from oi_list */ for ( oidx = &oi->oi_list; *oidx; oidx = &(*oidx)->on_next ) { if ( *oidx == on ) { *oidx = on->on_next; - bi_orig = be->bd_info; - be->bd_info = (BackendInfo *)on; - if ( on->on_bi.bi_db_close ) { - on->on_bi.bi_db_close( be, NULL ); - } - if ( on->on_bi.bi_db_destroy ) { - on->on_bi.bi_db_destroy( be, NULL ); - } - be->bd_info = bi_orig; - free( on ); break; } } - - /* clean up after removing last overlay */ - if ( ! oi->oi_list ) - { - /* reset db flags and bd_info to orig */ - be->bd_info = oi->oi_orig; - ch_free(oi); - } + + /* The db_close and db_destroy handlers to cleanup a release + * the overlay's resources are called from the cleanup callback + */ + rm_ctx = op->o_tmpalloc( sizeof( ov_remove_ctx ), op->o_tmpmemctx ); + rm_ctx->be = be; + rm_ctx->on = on; + + rm_cb = op->o_tmpalloc( sizeof( slap_callback ), op->o_tmpmemctx ); + rm_cb->sc_next = NULL; + rm_cb->sc_cleanup = overlay_remove_cb; + rm_cb->sc_response = NULL; + rm_cb->sc_private = (void*) rm_ctx; + + /* Append callback to the end of the list */ + for ( cb = op->o_callback; cb->sc_next; cb = cb->sc_next ); + cb->sc_next = rm_cb; } #endif /* SLAP_CONFIG_DELETE */ diff --git a/servers/slapd/bconfig.c b/servers/slapd/bconfig.c index 55f9dcdf03..b71c569c09 100644 --- a/servers/slapd/bconfig.c +++ b/servers/slapd/bconfig.c @@ -6176,13 +6176,8 @@ config_back_delete( Operation *op, SlapReply *rs ) rs->sr_text = "Cannot delete global overlays"; ldap_pvt_thread_pool_resume( &connection_pool ); goto out; - } else if ( ce->ce_be == op->o_bd->bd_self ) { - rs->sr_err = LDAP_UNWILLING_TO_PERFORM; - rs->sr_text = "Cannot delete cn=config overlays"; - ldap_pvt_thread_pool_resume( &connection_pool ); - goto out; } else { - overlay_remove( ce->ce_be, (slap_overinst *)ce->ce_bi ); + overlay_remove( ce->ce_be, (slap_overinst *)ce->ce_bi, op ); } } else { /* Cft_Database*/ if ( ce->ce_be == frontendDB || ce->ce_be == op->o_bd ){ diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h index 53f3c0466b..6e38694d9c 100644 --- a/servers/slapd/proto-slap.h +++ b/servers/slapd/proto-slap.h @@ -483,7 +483,7 @@ LDAP_SLAPD_F (void) overlay_move LDAP_P(( BackendDB *be, slap_overinst *on, int idx )); #ifdef SLAP_CONFIG_DELETE LDAP_SLAPD_F (void) overlay_remove LDAP_P(( - BackendDB *be, slap_overinst *on )); + BackendDB *be, slap_overinst *on, Operation *op )); LDAP_SLAPD_F (void) overlay_unregister_control LDAP_P(( BackendDB *be, const char *oid )); -- 2.39.2