From: Jean-Frederic Clere Date: Tue, 1 Aug 2006 15:44:33 +0000 (+0000) Subject: Arrange the health_checker: add set_slotmem_storage_method(), X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ee0d40e5d2250c2977e15a3a3d6266462f3a4b88;p=thirdparty%2Fapache%2Fhttpd.git Arrange the health_checker: add set_slotmem_storage_method(), create_slotmem() and attach_slotmem(). Arrange corresponding files. Start using the health logic in the balancer. Arrange ap_proxy_add_worker_to_balancer(). git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/httpd-proxy-scoreboard@427623 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/modules/proxy/health_checker_util.c b/modules/proxy/health_checker_util.c index a20235d738c..b4488590ea8 100644 --- a/modules/proxy/health_checker_util.c +++ b/modules/proxy/health_checker_util.c @@ -124,6 +124,36 @@ static apr_status_t test_backend(char *scheme, char *hostname, int port, apr_poo return APR_SUCCESS; } +/* set the storage to use */ +static void set_slotmem_storage_method(const slotmem_storage_method *storage) +{ + checkstorage = storage; +} + +static apr_status_t create_slotmem(char *name, int item_num, apr_pool_t *pool) +{ + apr_status_t rv; + if (checkstorage == NULL) + return APR_EGENERAL; + + rv = checkstorage->ap_slotmem_create(&myscore, name, sizeof(struct proxy_worker_conf), item_num, pool); + return rv; +} + +static apr_status_t attach_slotmem(char *name, int *item_num, apr_pool_t *pool) +{ + apr_status_t rv; + apr_size_t item_size; + if (checkstorage == NULL) + return APR_EGENERAL; + + rv = checkstorage->ap_slotmem_attach(&myscore, name, &item_size, item_num, pool); + if (rv != APR_SUCCESS) + return rv; + if (item_size != sizeof(struct proxy_worker_conf)) + return APR_ENOSHMAVAIL; + return APR_SUCCESS; +} /* read the size of the entry: to create the shared area */ static int getentrysize() { @@ -328,7 +358,9 @@ static apr_status_t check_poolhealth(proxy_worker *worker, int id, apr_pool_t *p /* The stuff we provide */ static const health_worker_method worker_storage = { - &getentrysize, + &set_slotmem_storage_method, + &create_slotmem, + &attach_slotmem, &add_entry, &del_entry, &get_health, @@ -343,23 +375,3 @@ const health_worker_method *health_checker_get_storage() { return(&worker_storage); } - -/* handle the slotmem storage */ -void health_checker_init_slotmem_storage(const slotmem_storage_method * storage) -{ - checkstorage = storage; -} -const slotmem_storage_method * health_checker_get_slotmem_storage() -{ - return(checkstorage); -} - -/* handle the slotmen itself */ -void health_checker_init_slotmem(ap_slotmem_t *score) -{ - myscore = score; -} -ap_slotmem_t *health_checker_get_slotmem() -{ - return(myscore); -} diff --git a/modules/proxy/mod_proxy_balancer.c b/modules/proxy/mod_proxy_balancer.c index ff0322f6637..c23bdc8eeb9 100644 --- a/modules/proxy/mod_proxy_balancer.c +++ b/modules/proxy/mod_proxy_balancer.c @@ -23,6 +23,8 @@ #include "apr_version.h" #include "apr_hooks.h" +#include "mod_proxy_health_checker.h" + #if APR_HAVE_UNISTD_H #include /* for getpid() */ #endif @@ -181,11 +183,19 @@ static proxy_worker *find_route_worker(proxy_balancer *balancer, int i; int checking_standby = 0; int checked_standby = 0; - proxy_worker *worker; + const health_worker_method *worker_storage; + worker_storage = ap_lookup_provider(PROXY_CKMETHOD, "default", "0"); + while (!checked_standby) { worker = (proxy_worker *)balancer->workers->elts; for (i = 0; i < balancer->workers->nelts; i++, worker++) { + if (worker_storage) { + int health; + worker_storage->get_health(worker->id, &health); + if (health != HEALTH_OK) + continue; + } if ( (checking_standby ? !PROXY_WORKER_IS_STANDBY(worker) : PROXY_WORKER_IS_STANDBY(worker)) ) continue; if (*(worker->s->route) && strcmp(worker->s->route, route) == 0) { @@ -215,6 +225,12 @@ static proxy_worker *find_route_worker(proxy_balancer *balancer, proxy_worker *rworker = NULL; rworker = find_route_worker(balancer, worker->s->redirect, r); /* Check if the redirect worker is usable */ + if (rworker && worker_storage) { + int health; + worker_storage->get_health(worker->id, &health); + if (health != HEALTH_OK) + continue; + } if (rworker && !PROXY_WORKER_IS_USABLE(rworker)) { /* * If the worker is in error state run diff --git a/modules/proxy/mod_proxy_health_checker.c b/modules/proxy/mod_proxy_health_checker.c index 5a139a9efdd..c7a60099689 100644 --- a/modules/proxy/mod_proxy_health_checker.c +++ b/modules/proxy/mod_proxy_health_checker.c @@ -17,18 +17,20 @@ static int healthck_pre_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp) { - slotmem_storage_method *checkstorage; + const slotmem_storage_method *checkstorage; const health_worker_method *worker_storage; ap_slotmem_t *myscore; - checkstorage = ap_lookup_provider(SLOTMEM_STORAGE, "shared", "0"); - if (checkstorage) { - health_checker_init_slotmem_storage(checkstorage); - } worker_storage = ap_lookup_provider(PROXY_CKMETHOD, "default", "0"); - if (checkstorage && worker_storage) { - checkstorage->ap_slotmem_create(&myscore, "proxy/checker", worker_storage->getentrysize(), 128, pconf); - health_checker_init_slotmem(myscore); + if (worker_storage) { + checkstorage = ap_lookup_provider(SLOTMEM_STORAGE, "shared", "0"); + if (checkstorage) { + worker_storage->set_slotmem_storage_method(checkstorage); + } else { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, + "proxy: The health checker needs a shared memory slotmem provider"); + return APR_EGENERAL; + } } return OK; } @@ -40,6 +42,14 @@ static int healthck_post_config(apr_pool_t *pconf, apr_pool_t *plog, worker_storage = ap_lookup_provider(PROXY_CKMETHOD, "default", "0"); if (worker_storage) { + apr_status_t rv; + rv = worker_storage->create_slotmem("proxy/checker", ap_proxy_lb_workers(), pconf); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, + "proxy: BALANCER: The health checker can't create slotmem"); + return APR_EGENERAL; + } + while (s) { void *sconf = s->module_config; proxy_server_conf *conf; @@ -56,7 +66,7 @@ static int healthck_post_config(apr_pool_t *pconf, apr_pool_t *plog, for (j = 0; j< conf->balancers->nelts; j++) { proxy_worker *myworker = (proxy_worker *)balancer->workers->elts; for (k = 0; k < balancer->workers->nelts; k++) { - if (myworker->id == worker->id) { + if (strcmp(myworker->name, worker->name) == 0) { name = balancer->name; break; } @@ -64,6 +74,7 @@ static int healthck_post_config(apr_pool_t *pconf, apr_pool_t *plog, } if (name) break; + balancer++; } if (!name) { diff --git a/modules/proxy/mod_proxy_health_checker.h b/modules/proxy/mod_proxy_health_checker.h index dfcaa63321a..3fc109fd1ab 100644 --- a/modules/proxy/mod_proxy_health_checker.h +++ b/modules/proxy/mod_proxy_health_checker.h @@ -29,8 +29,12 @@ typedef struct health_worker_method health_worker_method; /* allow health check method on workers in a non httpd process */ struct health_worker_method { - /* read the size of the entry: to create the shared area */ - int (* getentrysize)(void); + /* set the slotmem_storage_method to use */ + void (*set_slotmem_storage_method)(const slotmem_storage_method *slotmem_storage); + /* create the slotmem to store the shared information */ + apr_status_t (*create_slotmem)(char *name, int item_num, apr_pool_t *pool); + /* attach to existing shared slotmem */ + apr_status_t (*attach_slotmem)(char *name, int *item_num, apr_pool_t *pool); /* copy the worker information in the shared area so the health-checker can extract the part it need */ apr_status_t (*add_entry)(proxy_worker *worker, const char *balancer_name, int id); /* XXX : Remove the entry */ @@ -101,6 +105,3 @@ struct proxy_worker_conf { * Other routines. */ const health_worker_method *health_checker_get_storage(); -void health_checker_init_slotmem_storage(const slotmem_storage_method * storage); -void health_checker_init_slotmem(ap_slotmem_t *score); -const slotmem_storage_method * health_checker_get_slotmem_storage(); diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c index a004555d55f..b21b70c51b8 100644 --- a/modules/proxy/proxy_util.c +++ b/modules/proxy/proxy_util.c @@ -1385,9 +1385,6 @@ ap_proxy_add_worker_to_balancer(apr_pool_t *pool, proxy_balancer *balancer, runtime = apr_array_push(balancer->workers); memcpy(runtime, worker, sizeof(proxy_worker)); - runtime->id = proxy_lb_workers; - /* Increase the total runtime count */ - proxy_lb_workers++; } diff --git a/support/proxymonitor.c b/support/proxymonitor.c index ad31c2d9249..ffb9157a26b 100644 --- a/support/proxymonitor.c +++ b/support/proxymonitor.c @@ -66,23 +66,22 @@ char *basedir = NULL; /* XXX: hack to use a part of the mod_sharedmem and mod_proxy_health_checker */ static apr_status_t init_healthck(apr_pool_t *pool, int *num) { - apr_size_t size; apr_status_t rv; const slotmem_storage_method *checkstorage; - ap_slotmem_t *myscore; - + + /* Initialise the providers */ sharedmem_initglobalpool(pool); + worker_storage = health_checker_get_storage(); checkstorage = sharedmem_getstorage(); - rv = checkstorage->ap_slotmem_attach(&myscore, "proxy/checker", &size, num, pool); + + worker_storage->set_slotmem_storage_method(checkstorage); + rv = worker_storage->attach_slotmem("proxy/checker", num, pool); + if (rv != APR_SUCCESS) { apr_file_printf(errfile, "Can't attach to httpd memory error: %d\n", rv); return rv; } - health_checker_init_slotmem_storage(checkstorage); - health_checker_init_slotmem(myscore); - worker_storage = health_checker_get_storage(); - return rv; }