diff --git a/modules/proxy/mod_proxy.c b/modules/proxy/mod_proxy.c index 2a4cb1c2a9..cefc3d0ead 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 841d6022d4..5615fbbabf 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 516f7e4d42..c5f7941876 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