-*- 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]
</usage>
</directivesynopsis>
+<directivesynopsis>
+ <name>BalancerPersist</name>
+ <description>Attempt to persist changes made by the Balancer Manager across restarts.</description>
+ <syntax>BalancerPersist On|Off</syntax>
+ <default>BalancerPersist Off</default>
+ <contextlist><context>server config</context><context>virtual host</context></contextlist>
+ <compatibility>BalancerPersist is only available in Apache HTTP Server 2.5.0
+ and later.</compatibility>
+ <usage>
+ <p>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.</p>
+ </usage>
+ <note type="warning"><title>Warning</title>
+ <p>Data is not persisted across a stop/start cycle.</p>
+ </note>
+</directivesynopsis>
+
+
<directivesynopsis>
<name>BalancerMember</name>
<description>Add a member to a load balancing group</description>
* 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" */
#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
#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;
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;
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;
"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,
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;
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);
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)",
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;
proxy_worker **workers;
proxy_worker *worker;
proxy_balancer_shared *bshm;
- unsigned int index;
balancer->max_workers = balancer->workers->nelts + balancer->growth;
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;
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;
}
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 */
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;