1
0
mirror of https://github.com/apache/httpd.git synced 2025-08-08 15:02:10 +03:00

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
This commit is contained in:
Jim Jagielski
2011-02-04 20:01:04 +00:00
parent 85ac025790
commit 55b9f8fba8
4 changed files with 121 additions and 13 deletions

View 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,

View 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.

View 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.

View 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;
}