From: Nick Kew Date: Wed, 26 Jul 2006 08:00:23 +0000 (+0000) Subject: Backport DBD fixes X-Git-Tag: 2.2.3~13 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e2148c757e61e68f440d1cefc5dfab6ba63154e3;p=thirdparty%2Fapache%2Fhttpd.git Backport DBD fixes git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.2.x@425659 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index 16dd45bc544..54d9606e7e9 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,10 @@ -*- coding: utf-8 -*- Changes with Apache 2.2.3 + *) mod_dbd: Fix dependence on virtualhost configuration in + defining prepared statements (possible segfault at startup + in user modules such as mod_authn_dbd). [Nick Kew] + *) Add optional 'scheme://' prefix to ServerName directive, allowing correct determination of the canonical server URL for use behind a proxy or offload device handling SSL; fixing diff --git a/STATUS b/STATUS index b83af65b2a8..44b205fb041 100644 --- a/STATUS +++ b/STATUS @@ -90,11 +90,6 @@ PATCHES PROPOSED TO BACKPORT FROM TRUNK: http://people.apache.org/~wrowe/mod_isapi-416293.zip +1 wrowe , fielding - * Fix dbd merge_config function to support prepared statements - PR#39386 - http://svn.apache.org/viewcvs.cgi?rev=396310&view=rev - +1 niq, rpluem, fielding - * mod_cache: Do not overwrite the Content-Type in the cache, for successfully revalidated cached objects. PR 39647. Trunk version of patch: @@ -131,13 +126,6 @@ PATCHES PROPOSED TO BACKPORT FROM TRUNK: I am willing to propose patches, but due to personal time constraints they will not show up before the second half of July. - * Fix virtualhost/per-directory configuration mismatch bug with - possible segfault at server startup. - http://mail-archives.apache.org/mod_mbox/httpd-dev/200607.mbox/<831327593.20060720023332%40engec.ru> - (+ long thread) - http://svn.apache.org/viewvc?view=rev&revision=424798 - +1 niq, rpluem, fielding - * mod_authn_alias: Add a check to make sure that the base provider and the alias names are different and also that the alias has not been registered before. PR#40051 diff --git a/modules/database/mod_dbd.c b/modules/database/mod_dbd.c index bb6b34210c7..c236fedd868 100644 --- a/modules/database/mod_dbd.c +++ b/modules/database/mod_dbd.c @@ -67,6 +67,10 @@ typedef enum { cmd_name, cmd_params, cmd_persist, cmd_min, cmd_keep, cmd_max, cmd_exp } cmd_parts; +static apr_hash_t *dbd_prepared_defns; + +/* a default DBDriver value that'll generate meaningful error messages */ +static const char *const no_dbdriver = "[DBDriver unset]"; #define ISINT(val) \ for (p = val; *p; ++p) \ @@ -142,12 +146,13 @@ static const char *dbd_param_flag(cmd_parms *cmd, void *cfg, int flag) DBD_DECLARE_NONSTD(void) ap_dbd_prepare(server_rec *s, const char *query, const char *label) { - svr_cfg *svr = ap_get_module_config(s->module_config, &dbd_module); dbd_prepared *prepared = apr_pcalloc(s->process->pool, sizeof(dbd_prepared)); prepared->label = label; prepared->query = query; - prepared->next = svr->prepared; - svr->prepared = prepared; + prepared->next = apr_hash_get(dbd_prepared_defns, s->server_hostname, + APR_HASH_KEY_STRING); + apr_hash_set(dbd_prepared_defns, s->server_hostname, APR_HASH_KEY_STRING, + prepared); } static const char *dbd_prepare(cmd_parms *cmd, void *cfg, const char *query, const char *label) @@ -182,7 +187,7 @@ static void *dbd_merge(apr_pool_t *pool, void *BASE, void *ADD) { svr_cfg *base = (svr_cfg*) BASE; svr_cfg *add = (svr_cfg*) ADD; svr_cfg *cfg = apr_pcalloc(pool, sizeof(svr_cfg)); - cfg->name = strcmp(add->name, "") ? add->name : base->name; + cfg->name = (add->name != no_dbdriver) ? add->name : base->name; cfg->params = strcmp(add->params, "") ? add->params : base->params; cfg->persist = (add->persist == -1) ? base->persist : add->persist; #if APR_HAS_THREADS @@ -192,6 +197,7 @@ static void *dbd_merge(apr_pool_t *pool, void *BASE, void *ADD) { cfg->exptime = (add->set&EXPTIME_SET) ? add->exptime : base->exptime; #endif cfg->set = add->set | base->set; + cfg->prepared = (add->prepared != NULL) ? add->prepared : base->prepared; return (void*) cfg; } /* A default nmin of >0 will help with generating meaningful @@ -204,7 +210,8 @@ static void *dbd_merge(apr_pool_t *pool, void *BASE, void *ADD) { static void *dbd_cfg(apr_pool_t *p, server_rec *x) { svr_cfg *svr = (svr_cfg*) apr_pcalloc(p, sizeof(svr_cfg)); - svr->name = svr->params = ""; /* don't risk segfault on misconfiguration */ + svr->params = ""; /* don't risk segfault on misconfiguration */ + svr->name = no_dbdriver; /* to generate meaningful error messages */ svr->persist = -1; #if APR_HAS_THREADS svr->nmin = DEFAULT_NMIN; @@ -295,8 +302,10 @@ static apr_status_t dbd_construct(void **db, void *params, apr_pool_t *pool) *db = rec; rv = dbd_prepared_init(rec->pool, svr, rec); if (rv != APR_SUCCESS) { + const char *errmsg = apr_dbd_error(rec->driver, rec->handle, rv); ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, rec->pool, - "DBD: failed to initialise prepared SQL statements"); + "DBD: failed to initialise prepared SQL statements: %s", + (errmsg ? errmsg : "[???]")); } return rv; } @@ -598,6 +607,23 @@ DBD_DECLARE_NONSTD(ap_dbd_t *) ap_dbd_cacquire(conn_rec *c) } #endif +static int dbd_pre_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp) +{ + dbd_prepared_defns = apr_hash_make(ptemp); + return OK; +} +static int dbd_post_config(apr_pool_t *pconf, apr_pool_t *plog, + apr_pool_t *ptemp, server_rec *s) +{ + svr_cfg *svr; + server_rec *sp; + for (sp = s; sp; sp = sp->next) { + svr = ap_get_module_config(sp->module_config, &dbd_module); + svr->prepared = apr_hash_get(dbd_prepared_defns, sp->server_hostname, + APR_HASH_KEY_STRING); + } + return OK; +} static void dbd_hooks(apr_pool_t *pool) { #if APR_HAS_THREADS @@ -609,6 +635,8 @@ static void dbd_hooks(apr_pool_t *pool) APR_REGISTER_OPTIONAL_FN(ap_dbd_cacquire); APR_REGISTER_OPTIONAL_FN(ap_dbd_prepare); apr_dbd_init(pool); + ap_hook_pre_config(dbd_pre_config, NULL, NULL, APR_HOOK_MIDDLE); + ap_hook_post_config(dbd_post_config, NULL, NULL, APR_HOOK_MIDDLE); } module AP_MODULE_DECLARE_DATA dbd_module = {