in modules/proxy/mod_proxy_balancer.c [1102:1367]
static int balancer_process_balancer_worker(request_rec *r, proxy_server_conf *conf,
proxy_balancer *bsel,
proxy_worker *wsel,
apr_table_t *params)
{
apr_status_t rv;
/* First set the params */
if (wsel) {
const char *val;
int was_usable = PROXY_WORKER_IS_USABLE(wsel);
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01192) "settings worker params");
if ((val = apr_table_get(params, "w_lf"))) {
int ival;
double fval = atof(val);
ival = fval * 100.0;
if (ival >= 100 && ival <= 10000) {
wsel->s->lbfactor = ival;
if (bsel)
recalc_factors(bsel);
}
}
if ((val = apr_table_get(params, "w_wr"))) {
if (*val && strlen(val) < sizeof(wsel->s->route))
strcpy(wsel->s->route, val);
else
*wsel->s->route = '\0';
}
if ((val = apr_table_get(params, "w_rr"))) {
if (*val && strlen(val) < sizeof(wsel->s->redirect))
strcpy(wsel->s->redirect, val);
else
*wsel->s->redirect = '\0';
}
/*
* TODO: Look for all 'w_status_#' keys and then loop thru
* on that # character, since the character == the flag
*/
if ((val = apr_table_get(params, "w_status_I"))) {
ap_proxy_set_wstatus(PROXY_WORKER_IGNORE_ERRORS_FLAG, atoi(val), wsel);
}
if ((val = apr_table_get(params, "w_status_N"))) {
ap_proxy_set_wstatus(PROXY_WORKER_DRAIN_FLAG, atoi(val), wsel);
}
if ((val = apr_table_get(params, "w_status_D"))) {
ap_proxy_set_wstatus(PROXY_WORKER_DISABLED_FLAG, atoi(val), wsel);
}
if ((val = apr_table_get(params, "w_status_H"))) {
ap_proxy_set_wstatus(PROXY_WORKER_HOT_STANDBY_FLAG, atoi(val), wsel);
}
if ((val = apr_table_get(params, "w_status_R"))) {
ap_proxy_set_wstatus(PROXY_WORKER_HOT_SPARE_FLAG, atoi(val), wsel);
}
if ((val = apr_table_get(params, "w_status_S"))) {
ap_proxy_set_wstatus(PROXY_WORKER_STOPPED_FLAG, atoi(val), wsel);
}
if ((val = apr_table_get(params, "w_status_C"))) {
ap_proxy_set_wstatus(PROXY_WORKER_HC_FAIL_FLAG, atoi(val), wsel);
}
if ((val = apr_table_get(params, "w_ls"))) {
int ival = atoi(val);
if (ival >= 0 && ival <= 99) {
wsel->s->lbset = ival;
}
}
if ((val = apr_table_get(params, "w_hi"))) {
apr_interval_time_t hci;
if (ap_timeout_parameter_parse(val, &hci, "ms") == APR_SUCCESS) {
if (hci >= AP_WD_TM_SLICE) {
wsel->s->interval = hci;
}
}
}
if ((val = apr_table_get(params, "w_hp"))) {
int ival = atoi(val);
if (ival >= 1) {
wsel->s->passes = ival;
}
}
if ((val = apr_table_get(params, "w_hf"))) {
int ival = atoi(val);
if (ival >= 1) {
wsel->s->fails = ival;
}
}
if ((val = apr_table_get(params, "w_hm"))) {
proxy_hcmethods_t *method = proxy_hcmethods;
for (; method->name; method++) {
if (!ap_cstr_casecmp(method->name, val) && method->implemented)
wsel->s->method = method->method;
}
}
if ((val = apr_table_get(params, "w_hu"))) {
if (*val && strlen(val) < sizeof(wsel->s->hcuri))
strcpy(wsel->s->hcuri, val);
else
*wsel->s->hcuri = '\0';
}
if (hc_valid_expr_f && (val = apr_table_get(params, "w_he"))) {
if (*val && hc_valid_expr_f(r, val) && strlen(val) < sizeof(wsel->s->hcexpr))
strcpy(wsel->s->hcexpr, val);
else
*wsel->s->hcexpr = '\0';
}
/* If the health check method doesn't support an expr, then null it */
if (wsel->s->method == NONE || wsel->s->method == TCP || wsel->s->method == CPING) {
*wsel->s->hcexpr = '\0';
}
/* if enabling, we need to reset all lb params */
if (bsel && !was_usable && PROXY_WORKER_IS_USABLE(wsel)) {
bsel->s->need_reset = 1;
}
}
if (bsel) {
const char *val;
int ival;
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01193)
"settings balancer params");
if ((val = apr_table_get(params, "b_lbm"))) {
if ((strlen(val) < (sizeof(bsel->s->lbpname)-1)) &&
strcmp(val, bsel->s->lbpname)) {
proxy_balancer_method *lbmethod;
lbmethod = ap_lookup_provider(PROXY_LBMETHOD, val, "0");
if (lbmethod) {
PROXY_STRNCPY(bsel->s->lbpname, val);
bsel->lbmethod = lbmethod;
bsel->s->wupdated = apr_time_now();
bsel->s->need_reset = 1;
}
}
}
if ((val = apr_table_get(params, "b_tmo"))) {
ival = atoi(val);
if (ival >= 0 && ival <= 7200) { /* 2 hrs enuff? */
bsel->s->timeout = apr_time_from_sec(ival);
}
}
if ((val = apr_table_get(params, "b_max"))) {
ival = atoi(val);
if (ival >= 0 && ival <= 99) {
bsel->s->max_attempts = ival;
bsel->s->max_attempts_set = 1;
}
}
if ((val = apr_table_get(params, "b_sforce"))) {
ival = atoi(val);
bsel->s->sticky_force = (ival != 0);
}
if ((val = apr_table_get(params, "b_ss")) && *val) {
if (strlen(val) < (sizeof(bsel->s->sticky_path)-1)) {
if (*val == '-' && *(val+1) == '\0')
*bsel->s->sticky_path = *bsel->s->sticky = '\0';
else {
char *path;
PROXY_STRNCPY(bsel->s->sticky_path, val);
PROXY_STRNCPY(bsel->s->sticky, val);
if ((path = strchr((char *)bsel->s->sticky, '|'))) {
*path++ = '\0';
PROXY_STRNCPY(bsel->s->sticky_path, path);
}
}
}
}
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(r->pool, bsel, conf, val);
if (!nworker && storage->num_free_slots(bsel->wslot)) {
#if APR_HAS_THREADS
if ((rv = PROXY_GLOBAL_LOCK(bsel)) != APR_SUCCESS) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01194)
"%s: Lock failed for adding worker",
bsel->s->name);
}
#endif
ret = ap_proxy_define_worker(conf->pool, &nworker, bsel, conf, val, 0);
if (!ret) {
unsigned int index;
proxy_worker_shared *shm;
PROXY_COPY_CONF_PARAMS(nworker, conf);
if ((rv = storage->grab(bsel->wslot, &index)) != APR_SUCCESS) {
ap_log_rerror(APLOG_MARK, APLOG_EMERG, rv, r, APLOGNO(01195)
"worker slotmem_grab failed");
#if APR_HAS_THREADS
if ((rv = PROXY_GLOBAL_UNLOCK(bsel)) != APR_SUCCESS) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01196)
"%s: Unlock failed for adding worker",
bsel->s->name);
}
#endif
return HTTP_BAD_REQUEST;
}
if ((rv = storage->dptr(bsel->wslot, index, (void *)&shm)) != APR_SUCCESS) {
ap_log_rerror(APLOG_MARK, APLOG_EMERG, rv, r, APLOGNO(01197)
"worker slotmem_dptr failed");
#if APR_HAS_THREADS
if ((rv = PROXY_GLOBAL_UNLOCK(bsel)) != APR_SUCCESS) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01198)
"%s: Unlock failed for adding worker",
bsel->s->name);
}
#endif
return HTTP_BAD_REQUEST;
}
if ((rv = ap_proxy_share_worker(nworker, shm, index)) != APR_SUCCESS) {
ap_log_rerror(APLOG_MARK, APLOG_EMERG, rv, r, APLOGNO(01199)
"Cannot share worker");
#if APR_HAS_THREADS
if ((rv = PROXY_GLOBAL_UNLOCK(bsel)) != APR_SUCCESS) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01200)
"%s: Unlock failed for adding worker",
bsel->s->name);
}
#endif
return HTTP_BAD_REQUEST;
}
if ((rv = ap_proxy_initialize_worker(nworker, r->server, conf->pool)) != APR_SUCCESS) {
ap_log_rerror(APLOG_MARK, APLOG_EMERG, rv, r, APLOGNO(01201)
"Cannot init worker");
#if APR_HAS_THREADS
if ((rv = PROXY_GLOBAL_UNLOCK(bsel)) != APR_SUCCESS) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01202)
"%s: Unlock failed for adding worker",
bsel->s->name);
}
#endif
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(PROXY_WORKER_DISABLED_FLAG, 1, nworker);
} else {
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10163)
"%s: failed to add worker %s",
bsel->s->name, val);
#if APR_HAS_THREADS
PROXY_GLOBAL_UNLOCK(bsel);
#endif
return HTTP_BAD_REQUEST;
}
#if APR_HAS_THREADS
if ((rv = PROXY_GLOBAL_UNLOCK(bsel)) != APR_SUCCESS) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01203)
"%s: Unlock failed for adding worker",
bsel->s->name);
}
#endif
} else {
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10164)
"%s: failed to add worker %s",
bsel->s->name, val);
return HTTP_BAD_REQUEST;
}
}
}
return APR_SUCCESS;
}