diff --git a/servers/slapd/back-asyncmeta/config.c b/servers/slapd/back-asyncmeta/config.c index 5873d9c0a3..4f94e1ab04 100644 --- a/servers/slapd/back-asyncmeta/config.c +++ b/servers/slapd/back-asyncmeta/config.c @@ -1958,7 +1958,7 @@ asyncmeta_back_cf_gen( ConfigArgs *c ) return 1; } c->ca_private = mt; - c->cleanup = asyncmeta_cf_cleanup; + config_push_cleanup( c, asyncmeta_cf_cleanup ); } break; case LDAP_BACK_CFG_SUBTREE_EX: case LDAP_BACK_CFG_SUBTREE_IN: diff --git a/servers/slapd/back-mdb/config.c b/servers/slapd/back-mdb/config.c index 42e63dec14..160445aa75 100644 --- a/servers/slapd/back-mdb/config.c +++ b/servers/slapd/back-mdb/config.c @@ -445,7 +445,7 @@ mdb_cf_gen( ConfigArgs *c ) mdb->mi_flags |= MDB_RE_OPEN; ch_free( mdb->mi_dbenv_home ); mdb->mi_dbenv_home = NULL; - c->cleanup = mdb_cf_cleanup; + config_push_cleanup( c, mdb_cf_cleanup ); ldap_pvt_thread_pool_purgekey( mdb->mi_dbenv ); break; case MDB_DBNOSYNC: @@ -462,7 +462,7 @@ mdb_cf_gen( ConfigArgs *c ) rc = mdb_env_set_flags( mdb->mi_dbenv, mdb_envflags[i].mask, 0 ); if ( rc ) { mdb->mi_flags |= MDB_RE_OPEN; - c->cleanup = mdb_cf_cleanup; + config_push_cleanup( c, mdb_cf_cleanup ); rc = 0; } mdb->mi_dbenv_flags ^= mdb_envflags[i].mask; @@ -474,7 +474,7 @@ mdb_cf_gen( ConfigArgs *c ) rc = mdb_env_set_flags( mdb->mi_dbenv, mdb_envflags[i].mask, 0 ); if ( rc ) { mdb->mi_flags |= MDB_RE_OPEN; - c->cleanup = mdb_cf_cleanup; + config_push_cleanup( c, mdb_cf_cleanup ); rc = 0; } mdb->mi_dbenv_flags ^= mdb_envflags[i].mask; @@ -498,7 +498,7 @@ mdb_cf_gen( ConfigArgs *c ) } mdb->mi_defaultmask = 0; mdb->mi_flags |= MDB_DEL_INDEX; - c->cleanup = mdb_cf_cleanup; + config_push_cleanup( c, mdb_cf_cleanup ); } else { struct berval bv, def = BER_BVC("default"); @@ -535,7 +535,7 @@ mdb_cf_gen( ConfigArgs *c ) ai->ai_indexmask |= MDB_INDEX_DELETING; mdb->mi_flags |= MDB_DEL_INDEX; - c->cleanup = mdb_cf_cleanup; + config_push_cleanup( c, mdb_cf_cleanup ); } bv.bv_val[ bv.bv_len ] = sep; @@ -735,7 +735,7 @@ mdb_cf_gen( ConfigArgs *c ) rc = 0; if ( rc ) { mdb->mi_flags |= MDB_RE_OPEN; - c->cleanup = mdb_cf_cleanup; + config_push_cleanup( c, mdb_cf_cleanup ); rc = 0; } mdb->mi_dbenv_flags |= mdb_envflags[j].mask; @@ -757,7 +757,7 @@ mdb_cf_gen( ConfigArgs *c ) if( rc != LDAP_SUCCESS ) return 1; if ( mdb->mi_flags & MDB_IS_OPEN ) { mdb->mi_flags |= MDB_OPEN_INDEX; - c->cleanup = mdb_cf_cleanup; + config_push_cleanup( c, mdb_cf_cleanup ); if ( !mdb->mi_index_task ) { /* Start the task as soon as we finish here. Set a long * interval (10 hours) so that it only gets scheduled once. @@ -791,7 +791,7 @@ mdb_cf_gen( ConfigArgs *c ) mdb->mi_readers = c->value_int; if ( mdb->mi_flags & MDB_IS_OPEN ) { mdb->mi_flags |= MDB_RE_OPEN; - c->cleanup = mdb_cf_cleanup; + config_push_cleanup( c, mdb_cf_cleanup ); } break; @@ -799,7 +799,7 @@ mdb_cf_gen( ConfigArgs *c ) mdb->mi_mapsize = c->value_ulong; if ( mdb->mi_flags & MDB_IS_OPEN ) { mdb->mi_flags |= MDB_RE_OPEN; - c->cleanup = mdb_cf_cleanup; + config_push_cleanup( c, mdb_cf_cleanup ); } break; diff --git a/servers/slapd/back-meta/config.c b/servers/slapd/back-meta/config.c index 73926611ba..9495bf0d0c 100644 --- a/servers/slapd/back-meta/config.c +++ b/servers/slapd/back-meta/config.c @@ -2126,7 +2126,7 @@ meta_back_cf_gen( ConfigArgs *c ) return 1; } c->ca_private = mt; - c->cleanup = meta_cf_cleanup; + config_push_cleanup( c, meta_cf_cleanup ); } break; case LDAP_BACK_CFG_SUBTREE_EX: case LDAP_BACK_CFG_SUBTREE_IN: diff --git a/servers/slapd/back-wt/config.c b/servers/slapd/back-wt/config.c index 405617dcd0..fc2b435cc0 100644 --- a/servers/slapd/back-wt/config.c +++ b/servers/slapd/back-wt/config.c @@ -113,7 +113,7 @@ wt_cf_gen( ConfigArgs *c ) wi->wi_flags |= WT_OPEN_INDEX; if ( wi->wi_flags & WT_IS_OPEN ) { - c->cleanup = wt_cf_cleanup; + config_push_cleanup( c, wt_cf_cleanup ); if ( !wi->wi_index_task ) { /* Start the task as soon as we finish here. Set a long diff --git a/servers/slapd/config.c b/servers/slapd/config.c index 6570c9b22a..cab979a294 100644 --- a/servers/slapd/config.c +++ b/servers/slapd/config.c @@ -563,6 +563,35 @@ config_get_vals(ConfigTable *cf, ConfigArgs *c) return rc; } +int +config_push_cleanup(ConfigArgs *ca, ConfigDriver *cleanup) +{ + int i; + /* silently ignore redundant push */ + for (i=0; i < ca->num_cleanups; i++) { + if ( ca->cleanups[i] == cleanup ) + return 0; + } + + if (ca->num_cleanups >= SLAP_CONFIG_CLEANUP_MAX) + return -1; + ca->cleanups[ca->num_cleanups++] = cleanup; + return 0; +} + +int +config_run_cleanup(ConfigArgs *ca) +{ + int i, rc = 0; + + for (i=0; i < ca->num_cleanups; i++) { + rc = ca->cleanups[i](ca); + if (rc) + break; + } + return rc; +} + int init_config_attrs(ConfigTable *ct) { int i, code; diff --git a/servers/slapd/config.h b/servers/slapd/config.h index 4d5a85b892..8a4c7247df 100644 --- a/servers/slapd/config.h +++ b/servers/slapd/config.h @@ -168,8 +168,12 @@ typedef struct config_args_s { BackendInfo *bi; Entry *ca_entry; /* entry being modified */ void *ca_private; /* anything */ - ConfigDriver *cleanup; +#ifndef SLAP_CONFIG_CLEANUP_MAX +#define SLAP_CONFIG_CLEANUP_MAX 16 +#endif + ConfigDriver *cleanups[SLAP_CONFIG_CLEANUP_MAX]; ConfigType table; /* which config table did we come from */ + int num_cleanups; } ConfigArgs; /* If lineno is zero, we have an actual LDAP Add request from a client. @@ -195,6 +199,9 @@ int config_del_vals(ConfigTable *cf, ConfigArgs *c); int config_get_vals(ConfigTable *ct, ConfigArgs *c); int config_add_vals(ConfigTable *ct, ConfigArgs *c); +int config_push_cleanup(ConfigArgs *c, ConfigDriver *cleanup); +int config_run_cleanup(ConfigArgs *c); + void init_config_argv( ConfigArgs *c ); int init_config_attrs(ConfigTable *ct); int init_config_ocs( ConfigOCs *ocs ); diff --git a/servers/slapd/overlays/pcache.c b/servers/slapd/overlays/pcache.c index 10a711c7c3..e2bd101d0f 100644 --- a/servers/slapd/overlays/pcache.c +++ b/servers/slapd/overlays/pcache.c @@ -3781,7 +3781,7 @@ pc_ldadd( CfEntryInfo *p, Entry *e, ConfigArgs *ca ) ca->be = &cm->db; /* Defer open if this is an LDAPadd */ if ( CONFIG_ONLINE_ADD( ca )) - ca->cleanup = pc_ldadd_cleanup; + config_push_cleanup( ca, pc_ldadd_cleanup ); else cm->defer_db_open = 0; ca->ca_private = on; diff --git a/servers/slapd/overlays/translucent.c b/servers/slapd/overlays/translucent.c index 5d00645f48..c0b2ce6c40 100644 --- a/servers/slapd/overlays/translucent.c +++ b/servers/slapd/overlays/translucent.c @@ -146,7 +146,7 @@ translucent_ldadd( CfEntryInfo *cei, Entry *e, ConfigArgs *ca ) ca->be = &ov->db; ca->ca_private = on; if ( CONFIG_ONLINE_ADD( ca )) - ca->cleanup = translucent_ldadd_cleanup; + config_push_cleanup( ca, translucent_ldadd_cleanup ); else ov->defer_db_open = 0;