httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From yla...@apache.org
Subject svn commit: r1680920 - in /httpd/httpd/branches/2.2.x: CHANGES STATUS include/ap_mmn.h modules/proxy/mod_proxy.h modules/proxy/mod_proxy_balancer.c modules/proxy/proxy_util.c
Date Thu, 21 May 2015 16:24:31 GMT
Author: ylavic
Date: Thu May 21 16:24:30 2015
New Revision: 1680920

URL: http://svn.apache.org/r1680920
Log:
2.2.x only.

mod_proxy: Reuse proxy/balancer workers' parameters and scores across
graceful restarts, even if new workers are added, old ones removed, or
the order changes.

Proposed by: jkaluza
Reviewed by: ylavic, jkaluza, wrowe
Backported by: ylavic

Modified:
    httpd/httpd/branches/2.2.x/CHANGES
    httpd/httpd/branches/2.2.x/STATUS
    httpd/httpd/branches/2.2.x/include/ap_mmn.h
    httpd/httpd/branches/2.2.x/modules/proxy/mod_proxy.h
    httpd/httpd/branches/2.2.x/modules/proxy/mod_proxy_balancer.c
    httpd/httpd/branches/2.2.x/modules/proxy/proxy_util.c

Modified: httpd/httpd/branches/2.2.x/CHANGES
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.2.x/CHANGES?rev=1680920&r1=1680919&r2=1680920&view=diff
==============================================================================
--- httpd/httpd/branches/2.2.x/CHANGES [utf-8] (original)
+++ httpd/httpd/branches/2.2.x/CHANGES [utf-8] Thu May 21 16:24:30 2015
@@ -1,6 +1,10 @@
                                                          -*- coding: utf-8 -*-
 Changes with Apache 2.2.30
 
+  *) mod_proxy: Reuse proxy/balancer workers' parameters and scores across
+     graceful restarts, even if new workers are added, old ones removed, or
+     the order changes.  [Jan Kaluza, Yann Ylavic]
+
   *) mod_ssl: 'SSLProtocol ALL' was being ignored in virtual host context. 
      PR 57100.  [Michael Kaufmann <apache-bugzilla michael-kaufmann.ch>,
      Yann Ylavic]

Modified: httpd/httpd/branches/2.2.x/STATUS
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.2.x/STATUS?rev=1680920&r1=1680919&r2=1680920&view=diff
==============================================================================
--- httpd/httpd/branches/2.2.x/STATUS (original)
+++ httpd/httpd/branches/2.2.x/STATUS Thu May 21 16:24:30 2015
@@ -101,13 +101,6 @@ RELEASE SHOWSTOPPERS:
 PATCHES ACCEPTED TO BACKPORT FROM TRUNK:
   [ start all new proposals below, under PATCHES PROPOSED. ]
 
-   * mod_proxy: Reuse proxy workers' parameters and scores across graceful
-     restarts, even if new workers added, old ones removed, or the order
-     changes. PR 44736.  [Jan Kaluza]
-     2.2.x patch: http://people.apache.org/~ylavic/httpd-2.2.x-graceful_share_full-v7.patch
-     ylavic: trunk/2.4.x not concerned, 2.2.x only.
-     +1: ylavic, jkaluza, wrowe
-
    * mod_ssl: Propose a more modern Cipher and Protocol list, honor server cipher
      priority and add explanations relative to RFC 7525 guidance.
                   http://svn.apache.org/r1679428

Modified: httpd/httpd/branches/2.2.x/include/ap_mmn.h
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.2.x/include/ap_mmn.h?rev=1680920&r1=1680919&r2=1680920&view=diff
==============================================================================
--- httpd/httpd/branches/2.2.x/include/ap_mmn.h (original)
+++ httpd/httpd/branches/2.2.x/include/ap_mmn.h Thu May 21 16:24:30 2015
@@ -155,6 +155,7 @@
  * 20051115.35 (2.2.28) Add SSL reusable SNI to mod_proxy.h's proxy_conn_rec
  * 20051115.36 (2.2.28) Add r->trailers_{in,out}
  * 20051115.37 (2.2.30) Add ap_get_server_name_for_url()
+ * 20051115.38 (2.2.30) Add ap_proxy_set_scoreboard_lb() in mod_proxy.h
  */
 
 #define MODULE_MAGIC_COOKIE 0x41503232UL /* "AP22" */
@@ -162,7 +163,7 @@
 #ifndef MODULE_MAGIC_NUMBER_MAJOR
 #define MODULE_MAGIC_NUMBER_MAJOR 20051115
 #endif
-#define MODULE_MAGIC_NUMBER_MINOR 37                    /* 0...n */
+#define MODULE_MAGIC_NUMBER_MINOR 38                    /* 0...n */
 
 /**
  * Determine if the server's current MODULE_MAGIC_NUMBER is at least a

Modified: httpd/httpd/branches/2.2.x/modules/proxy/mod_proxy.h
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.2.x/modules/proxy/mod_proxy.h?rev=1680920&r1=1680919&r2=1680920&view=diff
==============================================================================
--- httpd/httpd/branches/2.2.x/modules/proxy/mod_proxy.h (original)
+++ httpd/httpd/branches/2.2.x/modules/proxy/mod_proxy.h Thu May 21 16:24:30 2015
@@ -293,6 +293,13 @@ PROXY_WORKER_DISABLED | PROXY_WORKER_STO
 #define PROXY_WORKER_DEFAULT_RETRY  60
 #define PROXY_WORKER_MAX_ROUTE_SIZ  63
 
+/* Scoreboard */
+#if MODULE_MAGIC_NUMBER_MAJOR > 20020903
+#define PROXY_HAS_SCOREBOARD 1
+#else
+#define PROXY_HAS_SCOREBOARD 0
+#endif
+
 /* Runtime worker status informations. Shared in scoreboard */
 typedef struct {
     int             status;
@@ -308,6 +315,9 @@ typedef struct {
     void            *context;   /* general purpose storage */
     apr_size_t      busy;       /* busyness factor */
     int             lbset;      /* load balancer cluster set */
+#if PROXY_HAS_SCOREBOARD
+    unsigned char   digest[APR_MD5_DIGESTSIZE]; /* hash of the worker->name */
+#endif
 } proxy_worker_stat;
 
 /* Worker configuration */
@@ -742,13 +752,6 @@ PROXY_DECLARE(int) ap_proxy_connection_c
 PROXY_DECLARE(void) ap_proxy_backend_broke(request_rec *r,
                                            apr_bucket_brigade *brigade);
 
-/* Scoreboard */
-#if MODULE_MAGIC_NUMBER_MAJOR > 20020903
-#define PROXY_HAS_SCOREBOARD 1
-#else
-#define PROXY_HAS_SCOREBOARD 0
-#endif
-
 /**
  * Transform buckets from one bucket allocator to another one by creating a
  * transient bucket for each data bucket and let it use the data read from
@@ -772,6 +775,12 @@ PROXY_DECLARE(apr_status_t)
 ap_proxy_buckets_lifetime_transform(request_rec *r, apr_bucket_brigade *from,
                                         apr_bucket_brigade *to);
 
+#if PROXY_HAS_SCOREBOARD
+void *ap_proxy_set_scoreboard_lb(proxy_worker *worker,
+                                 proxy_balancer *balancer,
+                                 server_rec *server);
+#endif
+
 #define PROXY_LBMETHOD "proxylbmethod"
 
 /* The number of dynamic workers that can be added when reconfiguring.

Modified: httpd/httpd/branches/2.2.x/modules/proxy/mod_proxy_balancer.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.2.x/modules/proxy/mod_proxy_balancer.c?rev=1680920&r1=1680919&r2=1680920&view=diff
==============================================================================
--- httpd/httpd/branches/2.2.x/modules/proxy/mod_proxy_balancer.c (original)
+++ httpd/httpd/branches/2.2.x/modules/proxy/mod_proxy_balancer.c Thu May 21 16:24:30 2015
@@ -83,25 +83,23 @@ static int init_balancer_members(proxy_s
     int i;
     proxy_worker *workers;
     int worker_is_initialized;
-    proxy_worker_stat *slot;
 
     workers = (proxy_worker *)balancer->workers->elts;
 
     for (i = 0; i < balancer->workers->nelts; i++) {
         worker_is_initialized = PROXY_WORKER_IS_INITIALIZED(workers);
+#if PROXY_HAS_SCOREBOARD
+        /*
+         * If the worker is not initialized but has a scoreboard
+         * slot, check whether it was already initialized in a
+         * previous generation to avoid resetting the shared lb
+         * parameters below.
+         */
         if (!worker_is_initialized) {
-            /*
-             * If the worker is not initialized check whether its scoreboard
-             * slot is already initialized.
-             */
-            slot = (proxy_worker_stat *) ap_get_scoreboard_lb(workers->id);
-            if (slot) {
-                worker_is_initialized = slot->status & PROXY_WORKER_INITIALIZED;
-            }
-            else {
-                worker_is_initialized = 0;
-            }
+            ap_proxy_set_scoreboard_lb(workers, balancer, s);
+            worker_is_initialized = PROXY_WORKER_IS_INITIALIZED(workers);
         }
+#endif
         ap_proxy_initialize_worker_share(conf, workers, s);
         ap_proxy_initialize_worker(workers, s);
         if (!worker_is_initialized) {

Modified: httpd/httpd/branches/2.2.x/modules/proxy/proxy_util.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.2.x/modules/proxy/proxy_util.c?rev=1680920&r1=1680919&r2=1680920&view=diff
==============================================================================
--- httpd/httpd/branches/2.2.x/modules/proxy/proxy_util.c (original)
+++ httpd/httpd/branches/2.2.x/modules/proxy/proxy_util.c Thu May 21 16:24:30 2015
@@ -1794,6 +1794,76 @@ static apr_status_t connection_destructo
 }
 #endif
 
+#if PROXY_HAS_SCOREBOARD
+void *ap_proxy_set_scoreboard_lb(proxy_worker *worker,
+                                 proxy_balancer *balancer,
+                                 server_rec *server)
+{
+    if (ap_scoreboard_image && !worker->s) {
+        int i = 0;
+        proxy_worker_stat *free_slot = NULL;
+        proxy_worker_stat *s;
+        unsigned char digest[APR_MD5_DIGESTSIZE];
+        apr_md5_ctx_t ctx;
+
+        /* The scoreboard entry must be unique per server and balancer,
+         * so when asked to (given by the caller) use their respective
+         * unique identifiers for the hash.
+         */
+        apr_md5_init(&ctx);
+        apr_md5_update(&ctx, (unsigned char *)worker->name,
+                       strlen(worker->name));
+        if (balancer) {
+            apr_md5_update(&ctx, (unsigned char *)balancer->name,
+                           strlen(balancer->name));
+        }
+        if (server) {
+            server_addr_rec *addr;
+            /* Assumes the unique identifier of a vhost is its address(es)
+             * plus the ServerName:Port. Should two or more vhosts have this
+             * same identifier, the first one would always be elected to
+             * handle the requests, so this shouldn't be an issue...
+             */
+            for (addr = server->addrs; addr; addr = addr->next) {
+                char host_ip[64]; /* for any IPv[46] string */
+                apr_sockaddr_ip_getbuf(host_ip, sizeof host_ip,
+                                       addr->host_addr);
+                apr_md5_update(&ctx, (unsigned char *)host_ip,
+                               strlen(host_ip));
+                apr_md5_update(&ctx, (unsigned char *)&addr->host_port,
+                               sizeof(addr->host_port));
+            }
+            apr_md5_update(&ctx, (unsigned char *)server->server_hostname,
+                           strlen(server->server_hostname));
+            apr_md5_update(&ctx, (unsigned char *)&server->port,
+                           sizeof(server->port));
+        }
+        apr_md5_final(digest, &ctx);
+
+        /* Try to find out the right shared memory according to the hash */
+        while ((s = (proxy_worker_stat *)ap_get_scoreboard_lb(i++)) != NULL) {
+            if ((s->status & PROXY_WORKER_INITIALIZED) == 0) {
+                if (free_slot == NULL) {
+                    free_slot = s;
+                }
+                continue;
+            }
+            if (memcmp(s->digest, digest, APR_MD5_DIGESTSIZE) == 0) {
+                worker->s = s;
+                return s;
+            }
+        }
+
+        /* We failed to find out shared memory, so just use a free slot (if any) */
+        if (free_slot) {
+            memcpy(free_slot->digest, digest, APR_MD5_DIGESTSIZE);
+            worker->s = free_slot;
+        }
+    }
+    return worker->s;
+}
+#endif
+
 /*
  * ap_proxy_initialize_worker_share() concerns itself
  * with initializing those parts of worker which
@@ -1803,11 +1873,7 @@ PROXY_DECLARE(void) ap_proxy_initialize_
                                                      proxy_worker *worker,
                                                      server_rec *s)
 {
-#if PROXY_HAS_SCOREBOARD
-    lb_score *score = NULL;
-#else
     void *score = NULL;
-#endif
 
     if (PROXY_WORKER_IS_INITIALIZED(worker)) {
         /* The worker share is already initialized */
@@ -1817,18 +1883,18 @@ PROXY_DECLARE(void) ap_proxy_initialize_
         return;
     }
 #if PROXY_HAS_SCOREBOARD
-        /* Get scoreboard slot */
+    /* Get scoreboard slot */
     if (ap_scoreboard_image) {
-        score = ap_get_scoreboard_lb(worker->id);
-        if (!score) {
+        if (!ap_proxy_set_scoreboard_lb(worker, NULL, s)) {
             ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
-                  "proxy: ap_get_scoreboard_lb(%d) failed in child %" APR_PID_T_FMT " for
worker %s",
+                  "proxy: ap_proxy_set_scoreboard_lb(%d) failed in child %" APR_PID_T_FMT
" for worker %s",
                   worker->id, getpid(), worker->name);
         }
         else {
              ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
                   "proxy: grabbed scoreboard slot %d in child %" APR_PID_T_FMT " for worker
%s",
                   worker->id, getpid(), worker->name);
+             score = worker->s;
         }
     }
 #endif
@@ -1837,8 +1903,8 @@ PROXY_DECLARE(void) ap_proxy_initialize_
         ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
               "proxy: initialized plain memory in child %" APR_PID_T_FMT " for worker %s",
               getpid(), worker->name);
+        worker->s = (proxy_worker_stat *)score;
     }
-    worker->s = (proxy_worker_stat *)score;
     /*
      * recheck to see if we've already been here. Possible
      * if proxy is using scoreboard to hold shared stats
@@ -1864,7 +1930,6 @@ PROXY_DECLARE(void) ap_proxy_initialize_
     }
 
     worker->s->status |= (worker->status | PROXY_WORKER_INITIALIZED);
-
 }
 
 PROXY_DECLARE(apr_status_t) ap_proxy_initialize_worker(proxy_worker *worker, server_rec *s)



Mime
View raw message