]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
Here we go... we can now, via balancer-manager, add new
authorJim Jagielski <jim@apache.org>
Fri, 4 Feb 2011 20:01:04 +0000 (20:01 +0000)
committerJim Jagielski <jim@apache.org>
Fri, 4 Feb 2011 20:01:04 +0000 (20:01 +0000)
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.

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1067269 13f79535-47bb-0310-9956-ffa450edef68

modules/proxy/mod_proxy.c
modules/proxy/mod_proxy.h
modules/proxy/mod_proxy_balancer.c
modules/proxy/proxy_util.c

index 2a4cb1c2a99dbd77943522866e0f2dd295c8b764..cefc3d0eada8ecd2c74642dd020d4b5f28f0237a 100644 (file)
@@ -52,16 +52,6 @@ APR_DECLARE_OPTIONAL_FN(char *, ssl_var_lookup,
 /* -------------------------------------------------------------- */
 /* 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,
index 841d6022d4acdd19325a780704ca6bbfdfc6a1fe..5615fbbabfb865f75ad5185b58b41cd591ba2d74 100644 (file)
@@ -299,6 +299,17 @@ PROXY_WORKER_DISABLED | PROXY_WORKER_STOPPED | PROXY_WORKER_IN_ERROR )
 
 #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_wstatus(char c, int set, proxy_worker *
  */
 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.
index 516f7e4d42131b48f965bdd466ba3df0e3abaf65..c5f79418762e7872ed58768251abe385eef70f57 100644 (file)
@@ -475,7 +475,7 @@ static int proxy_balancer_pre_request(proxy_worker **worker,
 
     /* 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 *r)
     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 *r)
                  * 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 *r)
                 }
             }
         }
+        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 *r)
             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_t *p, server_rec *s)
 
 }
 
+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.
index 3bbf1e34b27e9c032539cd9a494cd3b90c1b1b76..30efbed3c76225843111d40000cf1d7d4a6d90fb 100644 (file)
@@ -2886,3 +2886,4 @@ PROXY_DECLARE(char *) ap_proxy_parse_wstatus(apr_pool_t *p, proxy_worker *w)
         ret = apr_pstrcat(p, ret, "Ok ", NULL);
     return ret;
 }
+