]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
Backport DBD fixes
authorNick Kew <niq@apache.org>
Wed, 26 Jul 2006 08:00:23 +0000 (08:00 +0000)
committerNick Kew <niq@apache.org>
Wed, 26 Jul 2006 08:00:23 +0000 (08:00 +0000)
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.2.x@425659 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
STATUS
modules/database/mod_dbd.c

diff --git a/CHANGES b/CHANGES
index 16dd45bc5446827c1800be0ff76b2393f94c2cf1..54d9606e7e90ee4b44e55660d1fd39c04cdfeafb 100644 (file)
--- 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 b83af65b2a8b31cc16613b39347ba36f0f6b58cd..44b205fb0416bd523058501d6478c444b089dbb3 100644 (file)
--- 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
index bb6b34210c713d1110f765a5b774c9e80221a9b7..c236fedd86867a0f383645d57fc6a9a844119435 100644 (file)
@@ -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 = {