On Tuesday, April 12, 2011 18:24:28 William A. Rowe Jr. wrote:
> Suggestion - an EXEC_ON_READ 'DynamicModulesMax' directive, which would
> let us conf_vector_length = total_modules + dyn_modules_max; after the
> read_config, and finally lock down conf_vector_length = total_modules;
> at the end of post_config. WDYT?
The attached patch implements the DynamicModulesMax directive. It can appear
anywhere in the config file but is best placed *before* any LoadModule
directive. Up to post_config the number of prelinked modules plus
DynamicModulesMax is used as conf_vector_length. In core_post_config the
length is then settled on total_modules.
Torsten Förtsch
--
Need professional modperl support? Hire me! (http://foertsch.name)
Like fantasy? http://kabatinte.net
Index: server/config.c
===================================================================
--- server/config.c (revision 1094174)
+++ server/config.c (working copy)
@@ -181,22 +181,22 @@
static int total_modules = 0;
/* dynamic_modules is the number of modules that have been added
- * after the pre-loaded ones have been set up. It shouldn't be larger
- * than DYNAMIC_MODULE_LIMIT.
+ * after the pre-loaded ones have been set up. It should be at most
+ * dynamic_modules_max.
*/
static int dynamic_modules = 0;
-/* The maximum possible value for total_modules, i.e. number of static
- * modules plus DYNAMIC_MODULE_LIMIT.
+/* The maximum possible value for dynamic_modules. Shouldn't be larger than
+ * DYNAMIC_MODULE_LIMIT.
*/
-static int max_modules = 0;
+static int dynamic_modules_max;
/* The number of elements we need to alloc for config vectors. Before loading
- * of dynamic modules, we must be liberal and set this to max_modules. After
- * loading of dynamic modules, we can trim it down to total_modules. On
- * restart, reset to max_modules.
+ * of dynamic modules, we must be liberal and set this to the largest possible
+ * value (number of prelinked modules + dynamic_modules_max). After loading of
+ * dynamic modules, we can trim it down to total_modules.
*/
-static int conf_vector_length = 0;
+static int conf_vector_length;
AP_DECLARE_DATA module *ap_top_module = NULL;
AP_DECLARE_DATA module **ap_loaded_modules=NULL;
@@ -234,6 +234,22 @@
* overridden).
*/
+AP_DECLARE(void) ap_set_dynamic_modules_max(int lim)
+{
+ dynamic_modules_max = lim;
+ conf_vector_length = dynamic_modules_max + total_modules - dynamic_modules;
+}
+
+AP_DECLARE(int) ap_get_dynamic_modules_max(void)
+{
+ return dynamic_modules_max;
+}
+
+AP_DECLARE(void) ap_settle_module_count(void)
+{
+ conf_vector_length = total_modules;
+}
+
static ap_conf_vector_t *create_empty_config(apr_pool_t *p)
{
void *conf_vector = apr_pcalloc(p, sizeof(void *) * conf_vector_length);
@@ -542,7 +558,7 @@
}
if (m->module_index == -1) {
- if (dynamic_modules >= DYNAMIC_MODULE_LIMIT) {
+ if (dynamic_modules >= dynamic_modules_max) {
return apr_psprintf(p, "Module \"%s\" could not be loaded, "
"because the dynamic module limit was "
"reached. Please increase "
@@ -740,8 +756,7 @@
for (m = ap_preloaded_modules; *m != NULL; m++)
(*m)->module_index = total_modules++;
- max_modules = total_modules + DYNAMIC_MODULE_LIMIT + 1;
- conf_vector_length = max_modules;
+ ap_set_dynamic_modules_max(DYNAMIC_MODULE_LIMIT);
/*
* Initialise list of loaded modules and short names
@@ -2255,12 +2270,6 @@
}
-static apr_status_t reset_conf_vector_length(void *dummy)
-{
- conf_vector_length = max_modules;
- return APR_SUCCESS;
-}
-
AP_DECLARE(server_rec*) ap_read_config(process_rec *process, apr_pool_t *ptemp,
const char *filename,
ap_directive_t **conftree)
@@ -2272,6 +2281,7 @@
return s;
}
+ ap_set_dynamic_modules_max(DYNAMIC_MODULE_LIMIT);
init_config_globals(p);
/* All server-wide config files now have the SAME syntax... */
@@ -2309,14 +2319,6 @@
return NULL;
}
- /*
- * We have loaded the dynamic modules. From now on we know exactly how
- * long the config vectors need to be.
- */
- conf_vector_length = total_modules;
- apr_pool_cleanup_register(p, NULL, reset_conf_vector_length,
- apr_pool_cleanup_null);
-
error = process_command_config(s, ap_server_post_read_config, conftree,
p, ptemp);
Index: server/core.c
===================================================================
--- server/core.c (revision 1094174)
+++ server/core.c (working copy)
@@ -3167,6 +3167,19 @@
}
#endif
+static const char *set_dynamic_modules_max(cmd_parms *cmd, void *dummy,
+ const char *arg)
+{
+ const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE);
+
+ if (err != NULL) {
+ return err;
+ }
+
+ ap_set_dynamic_modules_max(atoi(arg));
+ return NULL;
+}
+
#ifdef RLIMIT_CPU
static const char *set_limit_cpu(cmd_parms *cmd, void *conf_,
const char *arg, const char *arg2)
@@ -3753,6 +3766,9 @@
"body"),
AP_INIT_RAW_ARGS("Mutex", ap_set_mutex, NULL, RSRC_CONF,
"mutex (or \"default\") and mechanism"),
+AP_INIT_TAKE1("DynamicModulesMax", set_dynamic_modules_max, NULL,
+ RSRC_CONF | EXEC_ON_READ,
+ "Limit on the number of dynamically loadable modules"),
/* System Resource Controls */
#ifdef RLIMIT_CPU
@@ -4175,6 +4191,12 @@
"or other system security module is loaded.");
return !OK;
}
+
+ /*
+ * We have loaded the dynamic modules. From now on we know exactly how
+ * long the config vectors need to be.
+ */
+ ap_settle_module_count();
return OK;
}
Index: modules/core/mod_so.c
===================================================================
--- modules/core/mod_so.c (revision 1094174)
+++ modules/core/mod_so.c (working copy)
@@ -113,8 +113,6 @@
so_server_conf *soc;
soc = (so_server_conf *)apr_pcalloc(p, sizeof(so_server_conf));
- soc->loaded_modules = apr_array_make(p, DYNAMIC_MODULE_LIMIT,
- sizeof(ap_module_symbol_t));
return (void *)soc;
}
@@ -179,6 +177,13 @@
*/
sconf = (so_server_conf *)ap_get_module_config(cmd->server->module_config,
&so_module);
+
+ if (!sconf->loaded_modules) {
+ sconf->loaded_modules = apr_array_make(cmd->pool,
+ ap_get_dynamic_modules_max(),
+ sizeof(ap_module_symbol_t));
+ }
+
modie = (ap_module_symbol_t *)sconf->loaded_modules->elts;
for (i = 0; i < sconf->loaded_modules->nelts; i++) {
modi = &modie[i];
@@ -339,13 +344,15 @@
sconf = (so_server_conf *)ap_get_module_config(s->module_config,
&so_module);
- modie = (ap_module_symbol_t *)sconf->loaded_modules->elts;
+ if (sconf->loaded_modules) {
+ modie = (ap_module_symbol_t *)sconf->loaded_modules->elts;
- for (i = 0; i < sconf->loaded_modules->nelts; i++) {
- modi = &modie[i];
- if (modi->name != NULL && strcmp(modi->name, modname) == 0) {
- return modi->modp;
- }
+ for (i = 0; i < sconf->loaded_modules->nelts; i++) {
+ modi = &modie[i];
+ if (modi->name != NULL && strcmp(modi->name, modname) == 0) {
+ return modi->modp;
+ }
+ }
}
return NULL;
}
@@ -378,12 +385,14 @@
}
}
- modie = (ap_module_symbol_t *)sconf->loaded_modules->elts;
- for (i = 0; i < sconf->loaded_modules->nelts; i++) {
- modi = &modie[i];
- if (modi->name != NULL) {
- apr_file_printf(out, " %s (shared)\n", modi->name);
- }
+ if (sconf->loaded_modules) {
+ modie = (ap_module_symbol_t *)sconf->loaded_modules->elts;
+ for (i = 0; i < sconf->loaded_modules->nelts; i++) {
+ modi = &modie[i];
+ if (modi->name != NULL) {
+ apr_file_printf(out, " %s (shared)\n", modi->name);
+ }
+ }
}
}
Index: modules/generators/mod_cgid.c
===================================================================
--- modules/generators/mod_cgid.c (revision 1094174)
+++ modules/generators/mod_cgid.c (working copy)
@@ -421,7 +421,7 @@
}
/* handle module indexes and such */
- rconf = (void **) apr_pcalloc(r->pool, sizeof(void *) * (total_modules + DYNAMIC_MODULE_LIMIT));
+ rconf = (void **)ap_create_request_config(r->pool);
temp_core = (core_request_config *)apr_palloc(r->pool, sizeof(core_module));
rconf[req->core_module_index] = (void *)temp_core;
Index: include/http_config.h
===================================================================
--- include/http_config.h (revision 1094174)
+++ include/http_config.h (working copy)
@@ -472,6 +472,25 @@
typedef struct ap_conf_vector_t ap_conf_vector_t;
/**
+ * Set the dynamic module limit. Used by the DynamicModulesMax directive.
+ * Also adjusts conf_vector_length.
+ * @param lim The limit.
+ */
+AP_DECLARE(void) ap_set_dynamic_modules_max(int lim);
+
+/**
+ * Get the dynamic module limit.
+ * @return The limit.
+ */
+AP_DECLARE(int) ap_get_dynamic_modules_max(void);
+
+/**
+ * When the number of modules has settled (in post_config) this function
+ * adjusts the conf_vector_length.
+ */
+AP_DECLARE(void) ap_settle_module_count(void);
+
+/**
* Generic accessors for other modules to get at their own module-specific
* data
* @param cv The vector in which the modules configuration is stored.