static int balancer_process_balancer_worker()

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;
}