1
0
mirror of https://github.com/apache/httpd.git synced 2025-08-08 15:02:10 +03:00

Use ap_state_query() to fix many modules that were not correctly initializing

if they were not active during server startup but got enabled later during a
graceful restart (in which case they need to do all work during a single
config run).


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1070153 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Stefan Fritsch
2011-02-12 21:23:56 +00:00
parent d6de9e9f67
commit 385da96d50
13 changed files with 33 additions and 105 deletions

View File

@@ -2,6 +2,10 @@
Changes with Apache 2.3.11 Changes with Apache 2.3.11
*) modules: Fix many modules that were not correctly initializing if they
were not active during server startup but got enabled later during a
graceful restart. [Stefan Fritsch]
*) core: Create new ap_state_query function that allows modules to determine *) core: Create new ap_state_query function that allows modules to determine
if the current configuration run is the initial one at server startup, if the current configuration run is the initial one at server startup,
and if the server is started for testing/config dumping only. and if the server is started for testing/config dumping only.

View File

@@ -382,18 +382,12 @@ static int pre_init(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp)
static int initialize_module(apr_pool_t *p, apr_pool_t *plog, static int initialize_module(apr_pool_t *p, apr_pool_t *plog,
apr_pool_t *ptemp, server_rec *s) apr_pool_t *ptemp, server_rec *s)
{ {
void *data;
const char *userdata_key = "auth_digest_init";
/* initialize_module() will be called twice, and if it's a DSO /* initialize_module() will be called twice, and if it's a DSO
* then all static data from the first call will be lost. Only * then all static data from the first call will be lost. Only
* set up our static data on the second call. */ * set up our static data on the second call. */
apr_pool_userdata_get(&data, userdata_key, s->process->pool); if (ap_state_query(AP_SQ_MAIN_STATE) == AP_SQ_MS_CREATE_PRE_CONFIG)
if (!data) {
apr_pool_userdata_set((const void *)1, userdata_key,
apr_pool_cleanup_null, s->process->pool);
return OK; return OK;
}
if (initialize_secret(s) != APR_SUCCESS) { if (initialize_secret(s) != APR_SUCCESS) {
return !OK; return !OK;
} }

View File

@@ -665,8 +665,6 @@ static int hm_post_config(apr_pool_t *p, apr_pool_t *plog,
apr_pool_t *ptemp, server_rec *s) apr_pool_t *ptemp, server_rec *s)
{ {
apr_status_t rv; apr_status_t rv;
const char *userdata_key = "mod_heartmonitor_init";
void *data;
hm_ctx_t *ctx = ap_get_module_config(s->module_config, hm_ctx_t *ctx = ap_get_module_config(s->module_config,
&heartmonitor_module); &heartmonitor_module);
APR_OPTIONAL_FN_TYPE(ap_watchdog_get_instance) *hm_watchdog_get_instance; APR_OPTIONAL_FN_TYPE(ap_watchdog_get_instance) *hm_watchdog_get_instance;
@@ -681,11 +679,8 @@ static int hm_post_config(apr_pool_t *p, apr_pool_t *plog,
} }
/* Create the slotmem */ /* Create the slotmem */
apr_pool_userdata_get(&data, userdata_key, s->process->pool); if (ap_state_query(AP_SQ_MAIN_STATE) == AP_SQ_MS_CREATE_CONFIG) {
if (!data) { /* this is the real thing */
/* first call do nothing */
apr_pool_userdata_set((const void *)1, userdata_key, apr_pool_cleanup_null, s->process->pool);
} else {
if (maxworkers) { if (maxworkers) {
storage = ap_lookup_provider(AP_SLOTMEM_PROVIDER_GROUP, "shared", "0"); storage = ap_lookup_provider(AP_SLOTMEM_PROVIDER_GROUP, "shared", "0");
if (!storage) { if (!storage) {

View File

@@ -20,6 +20,7 @@
#include "mod_watchdog.h" #include "mod_watchdog.h"
#include "ap_provider.h" #include "ap_provider.h"
#include "ap_mpm.h" #include "ap_mpm.h"
#include "http_core.h"
#include "util_mutex.h" #include "util_mutex.h"
#define AP_WATCHODG_PGROUP "watchdog" #define AP_WATCHODG_PGROUP "watchdog"
@@ -444,11 +445,12 @@ static int wd_post_config_hook(apr_pool_t *pconf, apr_pool_t *plog,
if (!(wd_server_conf = apr_pcalloc(pproc, sizeof(wd_server_conf_t)))) if (!(wd_server_conf = apr_pcalloc(pproc, sizeof(wd_server_conf_t))))
return APR_ENOMEM; return APR_ENOMEM;
apr_pool_create(&wd_server_conf->pool, pproc); apr_pool_create(&wd_server_conf->pool, pproc);
wd_server_conf->s = s; }
apr_pool_userdata_set(wd_server_conf, pk, apr_pool_cleanup_null, pproc);
if (ap_state_query(AP_SQ_MAIN_STATE) == AP_SQ_MS_CREATE_PRE_CONFIG)
/* First time config phase -- skip. */ /* First time config phase -- skip. */
return OK; return OK;
}
#if defined(WIN32) #if defined(WIN32)
{ {
const char *ppid = getenv("AP_PARENT_PID"); const char *ppid = getenv("AP_PARENT_PID");

View File

@@ -50,6 +50,7 @@
#include "httpd.h" #include "httpd.h"
#include "http_config.h" #include "http_config.h"
#include "http_core.h"
#include "http_log.h" #include "http_log.h"
#include "http_protocol.h" #include "http_protocol.h"
#include "util_mutex.h" #include "util_mutex.h"
@@ -117,35 +118,19 @@ static int exipc_pre_config(apr_pool_t *pconf, apr_pool_t *plog,
static int exipc_post_config(apr_pool_t *pconf, apr_pool_t *plog, static int exipc_post_config(apr_pool_t *pconf, apr_pool_t *plog,
apr_pool_t *ptemp, server_rec *s) apr_pool_t *ptemp, server_rec *s)
{ {
void *data; /* These two help ensure that we only init once. */
const char *userdata_key;
apr_status_t rs; apr_status_t rs;
exipc_data *base; exipc_data *base;
const char *tempdir; const char *tempdir;
/* /*
* The following checks if this routine has been called before. * Do nothing if we are not creating the final configuration.
* This is necessary because the parent process gets initialized * The parent process gets initialized a couple of times as the
* a couple of times as the server starts up, and we don't want * server starts up, and we don't want to create any more mutexes
* to create any more mutexes and shared memory segments than * and shared memory segments than we're actually going to use.
* we're actually going to use.
*
* The key needs to be unique for the entire web server, so put
* the module name in it.
*/ */
userdata_key = "example_ipc_init_module"; if (ap_state_query(AP_SQ_MAIN_STATE) == AP_SQ_MS_CREATE_PRE_CONFIG)
apr_pool_userdata_get(&data, userdata_key, s->process->pool);
if (!data) {
/*
* If no data was found for our key, this must be the first
* time the module is initialized. Put some data under that
* key and return.
*/
apr_pool_userdata_set((const void *) 1, userdata_key,
apr_pool_cleanup_null, s->process->pool);
return OK; return OK;
} /* Kilroy was here */
/* /*
* The shared memory allocation routines take a file name. * The shared memory allocation routines take a file name.

View File

@@ -891,7 +891,6 @@ static int cgid_init(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp,
server_rec *main_server) server_rec *main_server)
{ {
apr_proc_t *procnew = NULL; apr_proc_t *procnew = NULL;
int first_time = 0;
const char *userdata_key = "cgid_init"; const char *userdata_key = "cgid_init";
module **m; module **m;
int ret = OK; int ret = OK;
@@ -902,7 +901,6 @@ static int cgid_init(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp,
apr_pool_userdata_get(&data, userdata_key, main_server->process->pool); apr_pool_userdata_get(&data, userdata_key, main_server->process->pool);
if (!data) { if (!data) {
first_time = 1;
procnew = apr_pcalloc(main_server->process->pool, sizeof(*procnew)); procnew = apr_pcalloc(main_server->process->pool, sizeof(*procnew));
procnew->pid = -1; procnew->pid = -1;
procnew->err = procnew->in = procnew->out = NULL; procnew->err = procnew->in = procnew->out = NULL;
@@ -913,7 +911,7 @@ static int cgid_init(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp,
procnew = data; procnew = data;
} }
if (!first_time) { if (ap_state_query(AP_SQ_MAIN_STATE) != AP_SQ_MS_CREATE_PRE_CONFIG) {
char *tmp_sockname; char *tmp_sockname;
total_modules = 0; total_modules = 0;
for (m = ap_preloaded_modules; *m != NULL; m++) for (m = ap_preloaded_modules; *m != NULL; m++)

View File

@@ -2703,18 +2703,13 @@ static int util_ldap_post_config(apr_pool_t *p, apr_pool_t *plog,
ap_get_module_config(s->module_config, ap_get_module_config(s->module_config,
&ldap_module); &ldap_module);
void *data;
const char *userdata_key = "util_ldap_init";
apr_ldap_err_t *result_err = NULL; apr_ldap_err_t *result_err = NULL;
int rc; int rc;
/* util_ldap_post_config() will be called twice. Don't bother /* util_ldap_post_config() will be called twice. Don't bother
* going through all of the initialization on the first call * going through all of the initialization on the first call
* because it will just be thrown away.*/ * because it will just be thrown away.*/
apr_pool_userdata_get(&data, userdata_key, s->process->pool); if (ap_state_query(AP_SQ_MAIN_STATE) == AP_SQ_MS_CREATE_PRE_CONFIG) {
if (!data) {
apr_pool_userdata_set((const void *)1, userdata_key,
apr_pool_cleanup_null, s->process->pool);
#if APR_HAS_SHARED_MEMORY #if APR_HAS_SHARED_MEMORY
/* If the cache file already exists then delete it. Otherwise we are /* If the cache file already exists then delete it. Otherwise we are

View File

@@ -4309,16 +4309,6 @@ static int post_config(apr_pool_t *p,
server_rec *s) server_rec *s)
{ {
apr_status_t rv; apr_status_t rv;
void *data;
int first_time = 0;
const char *userdata_key = "rewrite_init_module";
apr_pool_userdata_get(&data, userdata_key, s->process->pool);
if (!data) {
first_time = 1;
apr_pool_userdata_set((const void *)1, userdata_key,
apr_pool_cleanup_null, s->process->pool);
}
/* check if proxy module is available */ /* check if proxy module is available */
proxy_available = (ap_find_linked_module("mod_proxy.c") != NULL); proxy_available = (ap_find_linked_module("mod_proxy.c") != NULL);
@@ -4331,12 +4321,11 @@ static int post_config(apr_pool_t *p,
apr_pool_cleanup_register(p, (void *)s, rewritelock_remove, apr_pool_cleanup_register(p, (void *)s, rewritelock_remove,
apr_pool_cleanup_null); apr_pool_cleanup_null);
/* step through the servers and /* if we are not doing the initial config, step through the servers and
* - open each rewriting logfile * open the RewriteMap prg:xxx programs,
* - open the RewriteMap prg:xxx programs
*/ */
for (; s; s = s->next) { if (ap_state_query(AP_SQ_MAIN_STATE) == AP_SQ_MS_CREATE_CONFIG) {
if (!first_time) { for (; s; s = s->next) {
if (run_rewritemap_programs(s, p) != APR_SUCCESS) { if (run_rewritemap_programs(s, p) != APR_SUCCESS) {
return HTTP_INTERNAL_SERVER_ERROR; return HTTP_INTERNAL_SERVER_ERROR;
} }

View File

@@ -387,19 +387,15 @@ static const proxy_balancer_method heartbeat =
static int lb_hb_init(apr_pool_t *p, apr_pool_t *plog, static int lb_hb_init(apr_pool_t *p, apr_pool_t *plog,
apr_pool_t *ptemp, server_rec *s) apr_pool_t *ptemp, server_rec *s)
{ {
const char *userdata_key = "mod_lbmethod_heartbeat_init";
void *data;
apr_size_t size; apr_size_t size;
unsigned int num; unsigned int num;
lb_hb_ctx_t *ctx = ap_get_module_config(s->module_config, lb_hb_ctx_t *ctx = ap_get_module_config(s->module_config,
&lbmethod_heartbeat_module); &lbmethod_heartbeat_module);
apr_pool_userdata_get(&data, userdata_key, s->process->pool); /* do nothing on first call */
if (!data) { if (ap_state_query(AP_SQ_MAIN_STATE) == AP_SQ_MS_CREATE_PRE_CONFIG)
/* first call do nothing */
apr_pool_userdata_set((const void *)1, userdata_key, apr_pool_cleanup_null, s->process->pool);
return OK; return OK;
}
storage = ap_lookup_provider(AP_SLOTMEM_PROVIDER_GROUP, "shared", "0"); storage = ap_lookup_provider(AP_SLOTMEM_PROVIDER_GROUP, "shared", "0");
if (!storage) { if (!storage) {
ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE, 0, s, "ap_lookup_provider %s failed", AP_SLOTMEM_PROVIDER_GROUP); ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE, 0, s, "ap_lookup_provider %s failed", AP_SLOTMEM_PROVIDER_GROUP);

View File

@@ -690,21 +690,15 @@ static int balancer_post_config(apr_pool_t *pconf, apr_pool_t *plog,
apr_pool_t *ptemp, server_rec *s) apr_pool_t *ptemp, server_rec *s)
{ {
apr_status_t rv; apr_status_t rv;
void *data;
void *sconf = s->module_config; void *sconf = s->module_config;
proxy_server_conf *conf = (proxy_server_conf *) ap_get_module_config(sconf, &proxy_module); proxy_server_conf *conf = (proxy_server_conf *) ap_get_module_config(sconf, &proxy_module);
const char *userdata_key = "mod_proxy_balancer_init";
ap_slotmem_instance_t *new = NULL; ap_slotmem_instance_t *new = NULL;
apr_time_t tstamp; apr_time_t tstamp;
/* balancer_post_config() will be called twice during startup. So, only /* balancer_post_config() will be called twice during startup. So, don't
* set up the static data the 1st time through. */ * set up the static data the 1st time through. */
apr_pool_userdata_get(&data, userdata_key, s->process->pool); if (ap_state_query(AP_SQ_MAIN_STATE) == AP_SQ_MS_CREATE_PRE_CONFIG)
if (!data) {
apr_pool_userdata_set((const void *)1, userdata_key,
apr_pool_cleanup_null, s->process->pool);
return OK; return OK;
}
/* /*
* Get slotmem setups * Get slotmem setups

View File

@@ -20,6 +20,7 @@
#include "apr_lib.h" #include "apr_lib.h"
#include "apr_strings.h" #include "apr_strings.h"
#include "http_log.h" #include "http_log.h"
#include "http_core.h"
#if APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION < 4 #if APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION < 4
@@ -41,7 +42,6 @@
#define LOG_PREFIX "mod_session_crypto: " #define LOG_PREFIX "mod_session_crypto: "
#define DRIVER_KEY "session_crypto_driver" #define DRIVER_KEY "session_crypto_driver"
#define INIT_KEY "session_crypto_init"
module AP_MODULE_DECLARE_DATA session_crypto_module; module AP_MODULE_DECLARE_DATA session_crypto_module;
@@ -390,7 +390,6 @@ AP_DECLARE(int) ap_session_crypto_decode(request_rec * r, session_rec * z)
AP_DECLARE(int) ap_session_crypto_init(apr_pool_t *p, apr_pool_t *plog, AP_DECLARE(int) ap_session_crypto_init(apr_pool_t *p, apr_pool_t *plog,
apr_pool_t *ptemp, server_rec *s) apr_pool_t *ptemp, server_rec *s)
{ {
void *data;
const apr_crypto_driver_t *driver = NULL; const apr_crypto_driver_t *driver = NULL;
session_crypto_conf *conf = ap_get_module_config(s->module_config, session_crypto_conf *conf = ap_get_module_config(s->module_config,
@@ -399,12 +398,8 @@ AP_DECLARE(int) ap_session_crypto_init(apr_pool_t *p, apr_pool_t *plog,
/* session_crypto_init() will be called twice. Don't bother /* session_crypto_init() will be called twice. Don't bother
* going through all of the initialization on the first call * going through all of the initialization on the first call
* because it will just be thrown away.*/ * because it will just be thrown away.*/
apr_pool_userdata_get(&data, INIT_KEY, s->process->pool); if (ap_state_query(AP_SQ_MAIN_STATE) == AP_SQ_MS_CREATE_PRE_CONFIG)
if (!data) {
apr_pool_userdata_set((const void *)1, INIT_KEY,
apr_pool_cleanup_null, s->process->pool);
return OK; return OK;
}
if (conf->library) { if (conf->library) {

View File

@@ -639,20 +639,7 @@ static void slotmem_shm_initialize_cleanup(apr_pool_t *p)
static int post_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, static int post_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp,
server_rec *s) server_rec *s)
{ {
void *data;
const char *userdata_key = "slotmem_shm_post_config";
slotmem_shm_initialize_cleanup(p); slotmem_shm_initialize_cleanup(p);
/* keep this around for possible future usage */
apr_pool_userdata_get(&data, userdata_key, s->process->pool);
if (!data) {
apr_pool_userdata_set((const void *)1, userdata_key,
apr_pool_cleanup_null, s->process->pool);
/* Do Stuff */
return OK;
}
return OK; return OK;
} }

View File

@@ -41,8 +41,6 @@ void ssl_scache_init(server_rec *s, apr_pool_t *p)
{ {
SSLModConfigRec *mc = myModConfig(s); SSLModConfigRec *mc = myModConfig(s);
apr_status_t rv; apr_status_t rv;
void *data;
const char *userdata_key = "ssl_scache_init";
struct ap_socache_hints hints; struct ap_socache_hints hints;
/* The very first invocation of this function will be the /* The very first invocation of this function will be the
@@ -50,12 +48,8 @@ void ssl_scache_init(server_rec *s, apr_pool_t *p)
* this first (and only the first) time through, since the pool * this first (and only the first) time through, since the pool
* will be immediately cleared anyway. For every subsequent * will be immediately cleared anyway. For every subsequent
* invocation, initialize the configured cache. */ * invocation, initialize the configured cache. */
apr_pool_userdata_get(&data, userdata_key, s->process->pool); if (!ap_state_query(AP_SQ_MAIN_STATE) == AP_SQ_MS_CREATE_PRE_CONFIG)
if (!data) {
apr_pool_userdata_set((const void *)1, userdata_key,
apr_pool_cleanup_null, s->process->pool);
return; return;
}
#ifdef HAVE_OCSP_STAPLING #ifdef HAVE_OCSP_STAPLING
if (mc->stapling_cache) { if (mc->stapling_cache) {