From aac783bdf533372c7b79c06aa01b45d27424402d Mon Sep 17 00:00:00 2001 From: Jim Jagielski Date: Fri, 18 Feb 2011 18:40:25 +0000 Subject: [PATCH] No longer depend on how fork() works when laying out segments... function pointers in shm are... nasty ;) git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1072098 13f79535-47bb-0310-9956-ffa450edef68 --- modules/proxy/mod_proxy.c | 7 ++++-- modules/proxy/mod_proxy.h | 14 +++++++---- modules/proxy/mod_proxy_balancer.c | 33 +++++++++++++----------- modules/proxy/proxy_util.c | 40 ++++++++++++++++++++---------- 4 files changed, 60 insertions(+), 34 deletions(-) diff --git a/modules/proxy/mod_proxy.c b/modules/proxy/mod_proxy.c index 76bb195e2b..1a5ad175c9 100644 --- a/modules/proxy/mod_proxy.c +++ b/modules/proxy/mod_proxy.c @@ -322,9 +322,12 @@ static const char *set_balancer_param(proxy_server_conf *conf, } else if (!strcasecmp(key, "lbmethod")) { proxy_balancer_method *provider; + if (strlen(val) > (sizeof(balancer->s->lbpname)-1)) + return "unknown lbmethod"; provider = ap_lookup_provider(PROXY_LBMETHOD, val, "0"); if (provider) { - balancer->s->lbmethod = provider; + balancer->lbmethod = provider; + PROXY_STRNCPY(balancer->s->lbpname, val); return NULL; } return "unknown lbmethod"; @@ -2309,7 +2312,7 @@ static int proxy_status_hook(request_rec *r, int flags) ap_rprintf(r, "%" APR_TIME_T_FMT "", apr_time_sec(balancer->s->timeout)); ap_rprintf(r, "%s\n", - balancer->s->lbmethod->name); + balancer->lbmethod->name); ap_rputs("\n", r); ap_rputs("\n\n" "" diff --git a/modules/proxy/mod_proxy.h b/modules/proxy/mod_proxy.h index b612b904ff..a658dff9a3 100644 --- a/modules/proxy/mod_proxy.h +++ b/modules/proxy/mod_proxy.h @@ -296,8 +296,11 @@ PROXY_WORKER_DISABLED | PROXY_WORKER_STOPPED | PROXY_WORKER_IN_ERROR ) #define PROXY_WORKER_MAX_SCHEME_SIZE 16 #define PROXY_WORKER_MAX_ROUTE_SIZE 64 #define PROXY_WORKER_MAX_NAME_SIZE 96 +#define PROXY_WORKER_MAX_HOSTNAME_SIZE 64 #define PROXY_BALANCER_MAX_STICKY_SIZE 64 +#define PROXY_MAX_PROVIDER_NAME_SIZE 16 + #define PROXY_STRNCPY(dst, src) apr_cpystrn((dst), (src), sizeof(dst)) #define PROXY_COPY_CONF_PARAMS(w, c) \ @@ -315,7 +318,7 @@ do { \ typedef struct { char name[PROXY_WORKER_MAX_NAME_SIZE]; char scheme[PROXY_WORKER_MAX_SCHEME_SIZE]; /* scheme to use ajp|http|https */ - char hostname[PROXY_WORKER_MAX_ROUTE_SIZE]; /* remote backend address */ + char hostname[PROXY_WORKER_MAX_HOSTNAME_SIZE]; /* remote backend address */ char route[PROXY_WORKER_MAX_ROUTE_SIZE]; /* balancing route */ char redirect[PROXY_WORKER_MAX_ROUTE_SIZE]; /* temporary balancing redirection route */ char flusher[PROXY_WORKER_MAX_SCHEME_SIZE]; /* flush provider used by mod_proxy_fdpass */ @@ -389,10 +392,10 @@ struct proxy_worker { typedef struct { char sticky_path[PROXY_BALANCER_MAX_STICKY_SIZE]; /* URL sticky session identifier */ char sticky[PROXY_BALANCER_MAX_STICKY_SIZE]; /* sticky session identifier */ + char lbpname[PROXY_MAX_PROVIDER_NAME_SIZE]; /* lbmethod provider name */ char nonce[APR_UUID_FORMATTED_LENGTH + 1]; apr_interval_time_t timeout; /* Timeout for waiting on free connection */ apr_time_t wupdated; /* timestamp of last change to workers list */ - proxy_balancer_method *lbmethod; int max_attempts; /* Number of attempts before failing */ int index; /* shm array index */ unsigned int sticky_force:1; /* Disable failover for sticky sessions */ @@ -413,6 +416,7 @@ struct proxy_balancer { const char *name; /* name of the load balancer */ const char *sname; /* filesystem safe balancer name */ apr_time_t wupdated; /* timestamp of last change to workers list */ + proxy_balancer_method *lbmethod; apr_global_mutex_t *gmutex; /* global lock for updating list of workers */ apr_thread_mutex_t *tmutex; /* Thread lock for updating shm */ void *context; /* general purpose storage */ @@ -857,14 +861,14 @@ PROXY_DECLARE(char *) ap_proxy_parse_wstatus(apr_pool_t *p, proxy_worker *w); /** - * Create readable representation of worker status bitfield + * Sync balancer and workers based on any updates w/i shm * @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); +PROXY_DECLARE(apr_status_t) ap_proxy_sync_balancer(proxy_balancer *b, server_rec *s, + proxy_server_conf *conf); /** diff --git a/modules/proxy/mod_proxy_balancer.c b/modules/proxy/mod_proxy_balancer.c index 2d67ec248d..9754bd39f2 100644 --- a/modules/proxy/mod_proxy_balancer.c +++ b/modules/proxy/mod_proxy_balancer.c @@ -331,7 +331,7 @@ static proxy_worker *find_best_worker(proxy_balancer *balancer, return NULL; } - candidate = (*balancer->s->lbmethod->finder)(balancer, r); + candidate = (*balancer->lbmethod->finder)(balancer, r); if (candidate) candidate->s->elected++; @@ -470,14 +470,14 @@ static int proxy_balancer_pre_request(proxy_worker **worker, /* Step 3.5: Update member list for the balancer */ /* TODO: Implement as provider! */ - ap_proxy_update_members(*balancer, r->server, conf); + ap_proxy_sync_balancer(*balancer, r->server, conf); /* Step 4: find the session route */ runtime = find_session_route(*balancer, r, &route, &sticky, url); if (runtime) { - if ((*balancer)->s->lbmethod && (*balancer)->s->lbmethod->updatelbstatus) { + if ((*balancer)->lbmethod && (*balancer)->lbmethod->updatelbstatus) { /* Call the LB implementation */ - (*balancer)->s->lbmethod->updatelbstatus(*balancer, runtime, r->server); + (*balancer)->lbmethod->updatelbstatus(*balancer, runtime, r->server); } else { /* Use the default one */ int i, total_factor = 0; @@ -874,7 +874,7 @@ static int balancer_handler(request_rec *r) "proxy: BALANCER: (%s). Lock failed for balancer_handler", balancer->name); } - ap_proxy_update_members(balancer, r->server, conf); + ap_proxy_sync_balancer(balancer, r->server, conf); if ((rv = PROXY_THREAD_UNLOCK(balancer)) != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_ERR, rv, r->server, "proxy: BALANCER: (%s). Unlock failed for balancer_handler", @@ -975,10 +975,15 @@ static int balancer_handler(request_rec *r) const char *val; int ival; if ((val = apr_table_get(params, "b_lbm"))) { - proxy_balancer_method *lbmethod; - lbmethod = ap_lookup_provider(PROXY_LBMETHOD, val, "0"); - if (lbmethod) - bsel->s->lbmethod = lbmethod; + if (strlen(val) < (sizeof(bsel->s->lbpname)-1)) { + proxy_balancer_method *lbmethod; + lbmethod = ap_lookup_provider(PROXY_LBMETHOD, bsel->s->lbpname, "0"); + if (lbmethod) { + PROXY_STRNCPY(bsel->s->lbpname, val); + bsel->lbmethod = lbmethod; + bsel->s->wupdated = apr_time_now(); + } + } } if ((val = apr_table_get(params, "b_tmo"))) { ival = atoi(val); @@ -997,7 +1002,7 @@ static int balancer_handler(request_rec *r) bsel->s->sticky_force = (ival != 0); } if ((val = apr_table_get(params, "b_ss")) && *val) { - if (strlen(val) < (PROXY_BALANCER_MAX_STICKY_SIZE-1)) { + if (strlen(val) < (sizeof(bsel->s->sticky_path)-1)) { if (*val == '-' && *(val+1) == '\0') *bsel->s->sticky_path = *bsel->s->sticky = '\0'; else { @@ -1075,9 +1080,9 @@ static int balancer_handler(request_rec *r) ap_log_error(APLOG_MARK, APLOG_ERR, rv, r->server, "proxy: BALANCER: (%s). Unlock failed for adding worker", bsel->name); - } + } } - + } } @@ -1156,7 +1161,7 @@ static int balancer_handler(request_rec *r) apr_time_sec(balancer->s->timeout)); ap_rprintf(r, "\n", balancer->s->max_attempts); ap_rprintf(r, "\n", - balancer->s->lbmethod->name); + balancer->s->lbpname); ap_rputs("
SchHostStat%d%s
\n
", r); ap_rputs("\n\n" "" @@ -1244,7 +1249,7 @@ static int balancer_handler(request_rec *r) pname = (ap_list_provider_names_t *)provs->elts; for (i = 0; i < provs->nelts; i++, pname++) { ap_rvputs(r,"
Worker URL