You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by ji...@apache.org on 2011/02/04 21:01:05 UTC

svn commit: r1067269 - in /httpd/httpd/trunk/modules/proxy: mod_proxy.c mod_proxy.h mod_proxy_balancer.c proxy_util.c

Author: jim
Date: Fri Feb  4 20:01:04 2011
New Revision: 1067269

URL: http://svn.apache.org/viewvc?rev=1067269&view=rev
Log:
Here we go... we can now, via balancer-manager, add new
workers to existing balancers. Still work to be done,
like error checking that we aren't trying to add more
than we can (right now, it fails, but it would be nice
to handle it nicer), disabling and *deleting* workers
we don't want anymore, the actual drain method, etc...
but this is some major goodness.

Modified:
    httpd/httpd/trunk/modules/proxy/mod_proxy.c
    httpd/httpd/trunk/modules/proxy/mod_proxy.h
    httpd/httpd/trunk/modules/proxy/mod_proxy_balancer.c
    httpd/httpd/trunk/modules/proxy/proxy_util.c

Modified: httpd/httpd/trunk/modules/proxy/mod_proxy.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/proxy/mod_proxy.c?rev=1067269&r1=1067268&r2=1067269&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/proxy/mod_proxy.c (original)
+++ httpd/httpd/trunk/modules/proxy/mod_proxy.c Fri Feb  4 20:01:04 2011
@@ -52,16 +52,6 @@ APR_DECLARE_OPTIONAL_FN(char *, ssl_var_
 /* -------------------------------------------------------------- */
 /* Translate the URL into a 'filename' */
 
-#define PROXY_COPY_CONF_PARAMS(w, c) \
-    do {                             \
-        (w)->s->timeout              = (c)->timeout;               \
-        (w)->s->timeout_set          = (c)->timeout_set;           \
-        (w)->s->recv_buffer_size     = (c)->recv_buffer_size;      \
-        (w)->s->recv_buffer_size_set = (c)->recv_buffer_size_set;  \
-        (w)->s->io_buffer_size       = (c)->io_buffer_size;        \
-        (w)->s->io_buffer_size_set   = (c)->io_buffer_size_set;    \
-    } while (0)
-
 static const char *set_worker_param(apr_pool_t *p,
                                     proxy_worker *worker,
                                     const char *key,

Modified: httpd/httpd/trunk/modules/proxy/mod_proxy.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/proxy/mod_proxy.h?rev=1067269&r1=1067268&r2=1067269&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/proxy/mod_proxy.h (original)
+++ httpd/httpd/trunk/modules/proxy/mod_proxy.h Fri Feb  4 20:01:04 2011
@@ -299,6 +299,17 @@ PROXY_WORKER_DISABLED | PROXY_WORKER_STO
 
 #define PROXY_STRNCPY(dst, src) apr_cpystrn((dst), (src), sizeof(dst))
 
+#define PROXY_COPY_CONF_PARAMS(w, c) \
+do {                             \
+(w)->s->timeout              = (c)->timeout;               \
+(w)->s->timeout_set          = (c)->timeout_set;           \
+(w)->s->recv_buffer_size     = (c)->recv_buffer_size;      \
+(w)->s->recv_buffer_size_set = (c)->recv_buffer_size_set;  \
+(w)->s->io_buffer_size       = (c)->io_buffer_size;        \
+(w)->s->io_buffer_size_set   = (c)->io_buffer_size_set;    \
+} while (0)
+
+
 /* Runtime worker status informations. Shared in scoreboard */
 typedef struct {
     char      name[PROXY_WORKER_MAX_NAME_SIZE];
@@ -841,6 +852,17 @@ PROXY_DECLARE(apr_status_t) ap_proxy_set
  */
 PROXY_DECLARE(char *) ap_proxy_parse_wstatus(apr_pool_t *p, proxy_worker *w);
 
+
+/**
+ * Create readable representation of worker status bitfield
+ * @param b  balancer to check/update member list of
+ * @param s  server rec
+ * @param conf config
+ * @return   APR_SUCCESS if all goes well
+ */
+PROXY_DECLARE(apr_status_t) ap_proxy_update_members(proxy_balancer *b, server_rec *s,
+                                                    proxy_server_conf *conf);
+
 #define PROXY_LBMETHOD "proxylbmethod"
 
 /* The number of dynamic workers that can be added when reconfiguring.

Modified: httpd/httpd/trunk/modules/proxy/mod_proxy_balancer.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/proxy/mod_proxy_balancer.c?rev=1067269&r1=1067268&r2=1067269&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/proxy/mod_proxy_balancer.c (original)
+++ httpd/httpd/trunk/modules/proxy/mod_proxy_balancer.c Fri Feb  4 20:01:04 2011
@@ -475,7 +475,7 @@ static int proxy_balancer_pre_request(pr
 
     /* Step 3.5: Update member list for the balancer */
     /* TODO: Implement as provider! */
-    /* proxy_update_members(balancer, r, conf); */
+    ap_proxy_update_members(*balancer, r->server, conf);
 
     /* Step 4: find the session route */
     runtime = find_session_route(*balancer, r, &route, &sticky, url);
@@ -875,6 +875,10 @@ static int balancer_handler(request_rec 
     conf = (proxy_server_conf *) ap_get_module_config(sconf, &proxy_module);
     params = apr_table_make(r->pool, 10);
 
+    balancer = (proxy_balancer *)conf->balancers->elts;
+    for (i = 0; i < conf->balancers->nelts; i++, balancer++)
+        ap_proxy_update_members(balancer, r->server, conf);
+
     if (r->args) {
         char *args = apr_pstrdup(r->pool, r->args);
         char *tok, *val;
@@ -887,7 +891,7 @@ static int balancer_handler(request_rec 
                  * Special case: workers are allowed path information
                  */
                 if ((access_status = ap_unescape_url(val)) != OK)
-                    if (strcmp(args, "w") || (access_status !=  HTTP_NOT_FOUND))
+                    if ((strcmp(args, "w") && strcmp(args, "b_nwrkr")) || (access_status !=  HTTP_NOT_FOUND))
                         return access_status;
                 apr_table_setn(params, args, val);
                 args = tok;
@@ -1005,6 +1009,43 @@ static int balancer_handler(request_rec 
                 }
             }
         }
+        if ((val = apr_table_get(params, "b_wyes")) &&
+            (*val == '1' && *(val+1) == '\0') &&
+            (val = apr_table_get(params, "b_nwrkr"))) {
+            char *ret;
+            proxy_worker *nworker;
+            nworker = ap_proxy_get_worker(conf->pool, bsel, conf, val);
+            if (!nworker) {
+                ret = ap_proxy_define_worker(conf->pool, &nworker, bsel, conf, val, 0);
+                if (!ret) {
+                    unsigned int index;
+                    apr_status_t rv;
+                    proxy_worker_shared *shm;
+                    PROXY_COPY_CONF_PARAMS(nworker, conf);
+                    if ((rv = storage->grab(bsel->slot, &index)) != APR_SUCCESS) {
+                        ap_log_error(APLOG_MARK, APLOG_EMERG, rv, r->server, "worker slotmem_grab failed");
+                        return HTTP_BAD_REQUEST;
+                    }
+                    if ((rv = storage->dptr(bsel->slot, index, (void *)&shm)) != APR_SUCCESS) {
+                        ap_log_error(APLOG_MARK, APLOG_EMERG, rv, r->server, "worker slotmem_dptr failed");
+                        return HTTP_BAD_REQUEST;
+                    }
+                    if ((rv = ap_proxy_share_worker(nworker, shm, index)) != APR_SUCCESS) {
+                        ap_log_error(APLOG_MARK, APLOG_EMERG, rv, r->server, "Cannot share worker");
+                        return HTTP_BAD_REQUEST;
+                    }
+                    if ((rv = ap_proxy_initialize_worker(nworker, r->server, conf->pool)) != APR_SUCCESS) {
+                        ap_log_error(APLOG_MARK, APLOG_EMERG, rv, r->server, "Cannot init worker");
+                        return HTTP_BAD_REQUEST;
+                    }
+                    /* sync all timestamps */
+                    bsel->wupdated = bsel->s->wupdated = nworker->s->updated = apr_time_now();
+                    /* by default, all new workers are disabled */
+                    ap_proxy_set_wstatus('D', 1, nworker);
+                }
+            }
+        }
+        
     }
 
     if (apr_table_get(params, "xml")) {
@@ -1186,7 +1227,10 @@ static int balancer_handler(request_rec 
             else {
                 ap_rvputs(r, "value ='", bsel->s->sticky, NULL);
             }
-            ap_rputs("'> (Use '-' to delete)</td></tr>\n", r);
+            ap_rputs("'>&nbsp;&nbsp;&nbsp;&nbsp;(Use '-' to delete)</td></tr>\n", r);
+            ap_rputs("<tr><td>Add New Worker:</td><td><input name='b_nwrkr' id='b_nwrkr' size=32 type=text>"
+                     "&nbsp;&nbsp;&nbsp;&nbsp;Are you sure? <input name='b_wyes' id='b_wyes' type=checkbox value='1'>"
+                     "</td></tr>", r);
             ap_rputs("<tr><td colspan=2><input type=submit value='Submit'></td></tr>\n", r);
             ap_rvputs(r, "</table>\n<input type=hidden name='b' id='b' ", NULL);
             ap_rvputs(r, "value='", bsel->name + sizeof(BALANCER_PREFIX) - 1,
@@ -1262,6 +1306,57 @@ static void balancer_child_init(apr_pool
 
 }
 
+PROXY_DECLARE(apr_status_t) ap_proxy_update_members(proxy_balancer *b, server_rec *s,
+                                                    proxy_server_conf *conf)
+{
+    proxy_worker **workers;
+    int i;
+    unsigned int index;
+    proxy_worker_shared *shm;
+    if (b->s->wupdated <= b->wupdated)
+        return APR_SUCCESS;
+    /*
+     * Look thru the list of workers in shm
+     * and see which one(s) we are lacking
+     */
+    for (index = 0; index < b->max_workers; index++) {
+        int found;
+        apr_status_t rv;
+        if ((rv = storage->dptr(b->slot, index, (void *)&shm)) != APR_SUCCESS) {
+            ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, "worker slotmem_dptr failed");
+            return APR_EGENERAL;
+        }
+        if (!shm->hash)
+            continue;
+        found = 0;
+        workers = (proxy_worker **)b->workers->elts;
+        for (i = 0; i < b->workers->nelts; i++, workers++) {
+            proxy_worker *worker = *workers;
+            if (worker->hash == shm->hash) {
+                found = 1;
+                break;
+            }
+        }
+        if (!found) {
+            proxy_worker **runtime;
+            runtime = apr_array_push(b->workers);
+            *runtime = apr_palloc(conf->pool, sizeof(proxy_worker));
+            (*runtime)->hash = shm->hash;
+            (*runtime)->context = NULL;
+            (*runtime)->cp = NULL;
+            (*runtime)->mutex = NULL;
+            (*runtime)->balancer = b;
+            (*runtime)->s = shm;
+            if ((rv = ap_proxy_initialize_worker(*runtime, s, conf->pool)) != APR_SUCCESS) {
+                ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, "Cannot init worker");
+                return rv;
+            }
+        }
+    }
+    b->wupdated = b->s->wupdated;
+    return APR_SUCCESS;
+}
+
 static void ap_proxy_balancer_register_hook(apr_pool_t *p)
 {
     /* Only the mpm_winnt has child init hook handler.

Modified: httpd/httpd/trunk/modules/proxy/proxy_util.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/proxy/proxy_util.c?rev=1067269&r1=1067268&r2=1067269&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/proxy/proxy_util.c (original)
+++ httpd/httpd/trunk/modules/proxy/proxy_util.c Fri Feb  4 20:01:04 2011
@@ -2886,3 +2886,4 @@ PROXY_DECLARE(char *) ap_proxy_parse_wst
         ret = apr_pstrcat(p, ret, "Ok ", NULL);
     return ret;
 }
+



Re: svn commit: r1067269 - in /httpd/httpd/trunk/modules/proxy: mod_proxy.c mod_proxy.h mod_proxy_balancer.c proxy_util.c

Posted by Jim Jagielski <ji...@jaguNET.com>.
On Feb 6, 2011, at 9:02 AM, Ruediger Pluem wrote:
>>     /* Step 3.5: Update member list for the balancer */
>>     /* TODO: Implement as provider! */
>> -    /* proxy_update_members(balancer, r, conf); */
>> +    ap_proxy_update_members(*balancer, r->server, conf);
> 
> Don't we need a lock here as well or better simply doing a lock in ap_proxy_update_members?
> 

I will be honest: I haven't really added in the required
locking cases yet... so there are a few places where we should
lock, but we don't yet.

>> +    for (index = 0; index < b->max_workers; index++) {
>> +        int found;
>> +        apr_status_t rv;
>> +        if ((rv = storage->dptr(b->slot, index, (void *)&shm)) != APR_SUCCESS) {
>> +            ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, "worker slotmem_dptr failed");
>> +            return APR_EGENERAL;
>> +        }
>> +        if (!shm->hash)
>> +            continue;
> 
> Can't we do a break here?

Not really, because in the future we will be, when we
delete members, creating "holes" in the inuse array, and
so we will need to go thru all the available slots
to account for those.


Re: svn commit: r1067269 - in /httpd/httpd/trunk/modules/proxy: mod_proxy.c mod_proxy.h mod_proxy_balancer.c proxy_util.c

Posted by Ruediger Pluem <rp...@apache.org>.

On 02/04/2011 09:01 PM, jim@apache.org wrote:
> Author: jim
> Date: Fri Feb  4 20:01:04 2011
> New Revision: 1067269
> 
> URL: http://svn.apache.org/viewvc?rev=1067269&view=rev
> Log:
> Here we go... we can now, via balancer-manager, add new
> workers to existing balancers. Still work to be done,
> like error checking that we aren't trying to add more
> than we can (right now, it fails, but it would be nice
> to handle it nicer), disabling and *deleting* workers
> we don't want anymore, the actual drain method, etc...
> but this is some major goodness.
> 
> Modified:
>     httpd/httpd/trunk/modules/proxy/mod_proxy.c
>     httpd/httpd/trunk/modules/proxy/mod_proxy.h
>     httpd/httpd/trunk/modules/proxy/mod_proxy_balancer.c
>     httpd/httpd/trunk/modules/proxy/proxy_util.c
> 
 URL:
http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/proxy/mod_proxy_balancer.c?rev=1067269&r1=1067268&r2=1067269&view=diff
> ==============================================================================
> --- httpd/httpd/trunk/modules/proxy/mod_proxy_balancer.c (original)
> +++ httpd/httpd/trunk/modules/proxy/mod_proxy_balancer.c Fri Feb  4 20:01:04 2011
> @@ -475,7 +475,7 @@ static int proxy_balancer_pre_request(pr
>  
>      /* Step 3.5: Update member list for the balancer */
>      /* TODO: Implement as provider! */
> -    /* proxy_update_members(balancer, r, conf); */
> +    ap_proxy_update_members(*balancer, r->server, conf);

Don't we need a lock here as well or better simply doing a lock in ap_proxy_update_members?

>  
>      /* Step 4: find the session route */
>      runtime = find_session_route(*balancer, r, &route, &sticky, url);
             ap_rvputs(r, "value='", bsel->name + sizeof(BALANCER_PREFIX) - 1,
> @@ -1262,6 +1306,57 @@ static void balancer_child_init(apr_pool
>  
>  }
>  
> +PROXY_DECLARE(apr_status_t) ap_proxy_update_members(proxy_balancer *b, server_rec *s,
> +                                                    proxy_server_conf *conf)
> +{
> +    proxy_worker **workers;
> +    int i;
> +    unsigned int index;
> +    proxy_worker_shared *shm;
> +    if (b->s->wupdated <= b->wupdated)
> +        return APR_SUCCESS;
> +    /*
> +     * Look thru the list of workers in shm
> +     * and see which one(s) we are lacking
> +     */
> +    for (index = 0; index < b->max_workers; index++) {
> +        int found;
> +        apr_status_t rv;
> +        if ((rv = storage->dptr(b->slot, index, (void *)&shm)) != APR_SUCCESS) {
> +            ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, "worker slotmem_dptr failed");
> +            return APR_EGENERAL;
> +        }
> +        if (!shm->hash)
> +            continue;

Can't we do a break here?

> +        found = 0;
> +        workers = (proxy_worker **)b->workers->elts;
> +        for (i = 0; i < b->workers->nelts; i++, workers++) {
> +            proxy_worker *worker = *workers;
> +            if (worker->hash == shm->hash) {
> +                found = 1;
> +                break;
> +            }
> +        }
> +        if (!found) {
> +            proxy_worker **runtime;
> +            runtime = apr_array_push(b->workers);
> +            *runtime = apr_palloc(conf->pool, sizeof(proxy_worker));
> +            (*runtime)->hash = shm->hash;
> +            (*runtime)->context = NULL;
> +            (*runtime)->cp = NULL;
> +            (*runtime)->mutex = NULL;
> +            (*runtime)->balancer = b;
> +            (*runtime)->s = shm;
> +            if ((rv = ap_proxy_initialize_worker(*runtime, s, conf->pool)) != APR_SUCCESS) {
> +                ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, "Cannot init worker");
> +                return rv;
> +            }
> +        }
> +    }
> +    b->wupdated = b->s->wupdated;
> +    return APR_SUCCESS;
> +}
> +
>  static void ap_proxy_balancer_register_hook(apr_pool_t *p)
>  {
>      /* Only the mpm_winnt has child init hook handler.
>