From 55b9f8fba8fa29a6f1179676d9492d34ba02cf93 Mon Sep 17 00:00:00 2001 From: Jim Jagielski Date: Fri, 4 Feb 2011 20:01:04 +0000 Subject: [PATCH] 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. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1067269 13f79535-47bb-0310-9956-ffa450edef68 --- modules/proxy/mod_proxy.c | 10 --- modules/proxy/mod_proxy.h | 22 +++++++ modules/proxy/mod_proxy_balancer.c | 101 ++++++++++++++++++++++++++++- modules/proxy/proxy_util.c | 1 + 4 files changed, 121 insertions(+), 13 deletions(-) diff --git a/modules/proxy/mod_proxy.c b/modules/proxy/mod_proxy.c index 2a4cb1c2a99..cefc3d0eada 100644 --- a/modules/proxy/mod_proxy.c +++ b/modules/proxy/mod_proxy.c @@ -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, diff --git a/modules/proxy/mod_proxy.h b/modules/proxy/mod_proxy.h index 841d6022d4a..5615fbbabfb 100644 --- a/modules/proxy/mod_proxy.h +++ b/modules/proxy/mod_proxy.h @@ -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. diff --git a/modules/proxy/mod_proxy_balancer.c b/modules/proxy/mod_proxy_balancer.c index 516f7e4d421..c5f79418762 100644 --- a/modules/proxy/mod_proxy_balancer.c +++ b/modules/proxy/mod_proxy_balancer.c @@ -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)\n", r); + ap_rputs("'>    (Use '-' to delete)\n", r); + ap_rputs("Add New Worker:" + "    Are you sure? " + "", r); ap_rputs("\n", r); ap_rvputs(r, "\n