From: Jim Jagielski Date: Tue, 18 Sep 2012 12:15:50 +0000 (+0000) Subject: Persist local balancer-manager changes across restart/graceful. X-Git-Tag: 2.5.0-alpha~6316 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=664dd95af2ba8946a778c607d4ebf24494d8ee3c;p=thirdparty%2Fapache%2Fhttpd.git Persist local balancer-manager changes across restart/graceful. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1387110 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index a5f19777ccd..48b89679374 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,10 @@ -*- coding: utf-8 -*- Changes with Apache 2.5.0 + *) mod_proxy: Allow for persistence of local changes (via the + balancer-manager) between graceful and normal restarts. + [Jim Jagielski] + *) mod_slotmem: New provider function, fgrab(), which forces an allocation of a slot. [Jim Jagielski] diff --git a/docs/manual/mod/mod_proxy.xml b/docs/manual/mod/mod_proxy.xml index 0691560c5ea..04c245f8bce 100644 --- a/docs/manual/mod/mod_proxy.xml +++ b/docs/manual/mod/mod_proxy.xml @@ -649,6 +649,26 @@ expressions + + BalancerPersist + Attempt to persist changes made by the Balancer Manager across restarts. + BalancerPersist On|Off + BalancerPersist Off + server configvirtual host + BalancerPersist is only available in Apache HTTP Server 2.5.0 + and later. + +

This directive will cause the shared memory storage associated + with the balancers and balancer members to be persisted across + restarts. This allows these local changes to not be lost during the + normal restart/graceful state transitions.

+
+ Warning +

Data is not persisted across a stop/start cycle.

+
+
+ + BalancerMember Add a member to a load balancing group diff --git a/include/ap_mmn.h b/include/ap_mmn.h index 70b763aae66..9c42f11b85a 100644 --- a/include/ap_mmn.h +++ b/include/ap_mmn.h @@ -400,6 +400,7 @@ * 20120724.0 (2.5.0-dev) Add hostname argument to ap_proxy_checkproxyblock. * 20120724.1 (2.5.0-dev) Add post_perdir_config hook. * 20120724.2 (2.5.0-dev) Add fgrab slotmem function to struct + * 20120724.3 (2.5.0-dev) Add bal_persist to proxy_server_conf */ #define MODULE_MAGIC_COOKIE 0x41503235UL /* "AP25" */ @@ -407,7 +408,7 @@ #ifndef MODULE_MAGIC_NUMBER_MAJOR #define MODULE_MAGIC_NUMBER_MAJOR 20120724 #endif -#define MODULE_MAGIC_NUMBER_MINOR 2 /* 0...n */ +#define MODULE_MAGIC_NUMBER_MINOR 3 /* 0...n */ /** * Determine if the server's current MODULE_MAGIC_NUMBER is at least a diff --git a/modules/proxy/mod_proxy.c b/modules/proxy/mod_proxy.c index 431efb87a0d..04f1a21cd85 100644 --- a/modules/proxy/mod_proxy.c +++ b/modules/proxy/mod_proxy.c @@ -1145,13 +1145,14 @@ static void * create_proxy_config(apr_pool_t *p, server_rec *s) #if 0 id = ap_proxy_hashfunc(apr_psprintf(p, "%pp-%" APR_TIME_T_FMT, ps, apr_time_now()), PROXY_HASHFUNC_DEFAULT); #else - id = ap_proxy_hashfunc(apr_psprintf(p, "%pp", ps), PROXY_HASHFUNC_DEFAULT); + id = ap_proxy_hashfunc(apr_psprintf(p, "%pp", s), PROXY_HASHFUNC_DEFAULT); #endif ps->id = apr_psprintf(p, "s%x", id); ps->viaopt = via_off; /* initially backward compatible with 1.3.1 */ ps->viaopt_set = 0; /* 0 means default */ ps->req = 0; ps->max_balancers = 0; + ps->bal_persist = 0; ps->bgrowth = 5; ps->bgrowth_set = 0; ps->req_set = 0; @@ -1197,6 +1198,7 @@ static void * merge_proxy_config(apr_pool_t *p, void *basev, void *overridesv) ps->bgrowth = (overrides->bgrowth_set == 0) ? base->bgrowth : overrides->bgrowth; ps->bgrowth_set = overrides->bgrowth_set || base->bgrowth_set; ps->max_balancers = overrides->max_balancers || base->max_balancers; + ps->bal_persist = overrides->bal_persist || base->bal_persist; ps->recv_buffer_size = (overrides->recv_buffer_size_set == 0) ? base->recv_buffer_size : overrides->recv_buffer_size; ps->recv_buffer_size_set = overrides->recv_buffer_size_set || base->recv_buffer_size_set; ps->io_buffer_size = (overrides->io_buffer_size_set == 0) ? base->io_buffer_size : overrides->io_buffer_size; @@ -1872,6 +1874,15 @@ static const char *set_bgrowth(cmd_parms *parms, void *dummy, const char *arg) return NULL; } +static const char *set_persist(cmd_parms *parms, void *dummy, int flag) +{ + proxy_server_conf *psf = + ap_get_module_config(parms->server->module_config, &proxy_module); + + psf->bal_persist = flag; + return NULL; +} + static const char *add_member(cmd_parms *cmd, void *dummy, const char *arg) { server_rec *s = cmd->server; @@ -2259,6 +2270,8 @@ static const command_rec proxy_cmds[] = "A balancer name and scheme with list of params"), AP_INIT_TAKE1("BalancerGrowth", set_bgrowth, NULL, RSRC_CONF, "Number of additional Balancers that can be added post-config"), + AP_INIT_FLAG("BalancerPersist", set_persist, NULL, RSRC_CONF, + "on if the balancer should persist changes on reboot/restart made via the Balancer Manager"), AP_INIT_TAKE1("ProxyStatus", set_status_opt, NULL, RSRC_CONF, "Configure Status: proxy status to one of: on | off | full"), AP_INIT_RAW_ARGS("ProxySet", set_proxy_param, NULL, RSRC_CONF|ACCESS_CONF, diff --git a/modules/proxy/mod_proxy.h b/modules/proxy/mod_proxy.h index 6cde1412f79..f1b64d6daa6 100644 --- a/modules/proxy/mod_proxy.h +++ b/modules/proxy/mod_proxy.h @@ -178,6 +178,7 @@ typedef struct { unsigned int proxy_status_set:1; unsigned int source_address_set:1; unsigned int bgrowth_set:1; + unsigned int bal_persist:1; } proxy_server_conf; diff --git a/modules/proxy/mod_proxy_balancer.c b/modules/proxy/mod_proxy_balancer.c index 1feb2d7cd05..1df20aa425c 100644 --- a/modules/proxy/mod_proxy_balancer.c +++ b/modules/proxy/mod_proxy_balancer.c @@ -744,6 +744,7 @@ static int balancer_post_config(apr_pool_t *pconf, apr_pool_t *plog, while (s) { int i,j; proxy_balancer *balancer; + ap_slotmem_type_t type; sconf = s->module_config; conf = (proxy_server_conf *)ap_get_module_config(sconf, &proxy_module); @@ -753,6 +754,11 @@ static int balancer_post_config(apr_pool_t *pconf, apr_pool_t *plog, s = s->next; continue; } + if (conf->bal_persist) { + type = AP_SLOTMEM_TYPE_PREGRAB | AP_SLOTMEM_TYPE_PERSIST; + } else { + type = AP_SLOTMEM_TYPE_PREGRAB; + } if (conf->balancers->nelts) { conf->max_balancers = conf->balancers->nelts + conf->bgrowth; ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01178) "Doing balancers create: %d, %d (%d)", @@ -761,7 +767,7 @@ static int balancer_post_config(apr_pool_t *pconf, apr_pool_t *plog, rv = storage->create(&new, conf->id, ALIGNED_PROXY_BALANCER_SHARED_SIZE, - conf->max_balancers, AP_SLOTMEM_TYPE_PREGRAB, pconf); + conf->max_balancers, type, pconf); if (rv != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, APLOGNO(01179) "balancer slotmem_create failed"); return !OK; @@ -776,7 +782,6 @@ static int balancer_post_config(apr_pool_t *pconf, apr_pool_t *plog, proxy_worker **workers; proxy_worker *worker; proxy_balancer_shared *bshm; - unsigned int index; balancer->max_workers = balancer->workers->nelts + balancer->growth; @@ -794,29 +799,29 @@ static int balancer_post_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_cleanup_null); /* setup shm for balancers */ - if ((rv = storage->grab(conf->bslot, &index)) != APR_SUCCESS) { + if ((rv = storage->fgrab(conf->bslot, i)) != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, APLOGNO(01181) "balancer slotmem_grab failed"); return !OK; } - if ((rv = storage->dptr(conf->bslot, index, (void *)&bshm)) != APR_SUCCESS) { + if ((rv = storage->dptr(conf->bslot, i, (void *)&bshm)) != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, APLOGNO(01182) "balancer slotmem_dptr failed"); return !OK; } - if ((rv = ap_proxy_share_balancer(balancer, bshm, index)) != APR_SUCCESS) { + if ((rv = ap_proxy_share_balancer(balancer, bshm, i)) != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, APLOGNO(01183) "Cannot share balancer"); return !OK; } /* create slotmem slots for workers */ - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01184) "Doing workers create: %s (%s), %d, %d", + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01184) "Doing workers create: %s (%s), %d, %d [%u]", balancer->s->name, balancer->s->sname, (int)ALIGNED_PROXY_WORKER_SHARED_SIZE, - (int)balancer->max_workers); + (int)balancer->max_workers, i); rv = storage->create(&new, balancer->s->sname, ALIGNED_PROXY_WORKER_SHARED_SIZE, - balancer->max_workers, AP_SLOTMEM_TYPE_PREGRAB, pconf); + balancer->max_workers, type, pconf); if (rv != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, APLOGNO(01185) "worker slotmem_create failed"); return !OK; @@ -833,21 +838,26 @@ static int balancer_post_config(apr_pool_t *pconf, apr_pool_t *plog, proxy_worker_shared *shm; worker = *workers; - if ((rv = storage->grab(balancer->wslot, &index)) != APR_SUCCESS) { + if ((rv = storage->fgrab(balancer->wslot, j)) != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, APLOGNO(01186) "worker slotmem_grab failed"); return !OK; } - if ((rv = storage->dptr(balancer->wslot, index, (void *)&shm)) != APR_SUCCESS) { + if ((rv = storage->dptr(balancer->wslot, j, (void *)&shm)) != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, APLOGNO(01187) "worker slotmem_dptr failed"); return !OK; } - if ((rv = ap_proxy_share_worker(worker, shm, index)) != APR_SUCCESS) { + if ((rv = ap_proxy_share_worker(worker, shm, j)) != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, APLOGNO(01188) "Cannot share worker"); return !OK; } worker->s->updated = tstamp; } + if (conf->bal_persist) { + /* We could have just read-in a persisted config. Force a sync. */ + balancer->wupdated--; + ap_proxy_sync_balancer(balancer, s, conf); + } } s = s->next; } diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c index a69483ba4a5..983c289c380 100644 --- a/modules/proxy/proxy_util.c +++ b/modules/proxy/proxy_util.c @@ -1198,9 +1198,12 @@ PROXY_DECLARE(apr_status_t) ap_proxy_share_balancer(proxy_balancer *balancer, if (!shm || !balancer->s) return APR_EINVAL; - memcpy(shm, balancer->s, sizeof(proxy_balancer_shared)); - if (balancer->s->was_malloced) - free(balancer->s); + if ((balancer->s->hash.def != shm->hash.def) || + (balancer->s->hash.fnv != shm->hash.fnv)) { + memcpy(shm, balancer->s, sizeof(proxy_balancer_shared)); + if (balancer->s->was_malloced) + free(balancer->s); + } balancer->s = shm; balancer->s->index = i; /* the below should always succeed */ @@ -1637,9 +1640,13 @@ PROXY_DECLARE(apr_status_t) ap_proxy_share_worker(proxy_worker *worker, proxy_wo if (!shm || !worker->s) return APR_EINVAL; - memcpy(shm, worker->s, sizeof(proxy_worker_shared)); - if (worker->s->was_malloced) - free(worker->s); /* was malloced in ap_proxy_define_worker */ + if ((worker->s->hash.def != shm->hash.def) || + (worker->s->hash.fnv != shm->hash.fnv)) { + memcpy(shm, worker->s, sizeof(proxy_worker_shared)); + if (worker->s->was_malloced) + free(worker->s); /* was malloced in ap_proxy_define_worker */ + } + worker->s = shm; worker->s->index = i; return APR_SUCCESS;