Commit 16df8ce5 authored by Jim Jagielski's avatar Jim Jagielski
Browse files

No longer depend on how fork() works when laying out segments...

function pointers in shm are... nasty ;)

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1072098 13f79535-47bb-0310-9956-ffa450edef68
parent e180b50f
Loading
Loading
Loading
Loading
+5 −2
Changes for modules/proxy/mod_proxy.c: 5 added lines, 2 removed lines.
Original line number Diff line number Diff line
@@ -322,9 +322,12 @@ static const char *set_balancer_param(proxy_server_conf *conf,
    }
    else if (!strcasecmp(key, "lbmethod")) {
        proxy_balancer_method *provider;
        if (strlen(val) > (sizeof(balancer->s->lbpname)-1))
            return "unknown lbmethod";
        provider = ap_lookup_provider(PROXY_LBMETHOD, val, "0");
        if (provider) {
            balancer->s->lbmethod = provider;
            balancer->lbmethod = provider;
            PROXY_STRNCPY(balancer->s->lbpname, val);
            return NULL;
        }
        return "unknown lbmethod";
@@ -2309,7 +2312,7 @@ static int proxy_status_hook(request_rec *r, int flags)
        ap_rprintf(r, "</td><td>%" APR_TIME_T_FMT "</td>",
                   apr_time_sec(balancer->s->timeout));
        ap_rprintf(r, "<td>%s</td>\n",
                   balancer->s->lbmethod->name);
                   balancer->lbmethod->name);
        ap_rputs("</table>\n", r);
        ap_rputs("\n\n<table border=\"0\"><tr>"
                 "<th>Sch</th><th>Host</th><th>Stat</th>"
+8 −4
Changes for modules/proxy/mod_proxy.h: 8 added lines, 4 removed lines.
Original line number Diff line number Diff line
@@ -296,8 +296,11 @@ PROXY_WORKER_DISABLED | PROXY_WORKER_STOPPED | PROXY_WORKER_IN_ERROR )
#define PROXY_WORKER_MAX_SCHEME_SIZE    16
#define PROXY_WORKER_MAX_ROUTE_SIZE     64
#define PROXY_WORKER_MAX_NAME_SIZE      96
#define PROXY_WORKER_MAX_HOSTNAME_SIZE  64
#define PROXY_BALANCER_MAX_STICKY_SIZE  64

#define PROXY_MAX_PROVIDER_NAME_SIZE    16

#define PROXY_STRNCPY(dst, src) apr_cpystrn((dst), (src), sizeof(dst))

#define PROXY_COPY_CONF_PARAMS(w, c) \
@@ -315,7 +318,7 @@ do { \
typedef struct {
    char      name[PROXY_WORKER_MAX_NAME_SIZE];
    char      scheme[PROXY_WORKER_MAX_SCHEME_SIZE];   /* scheme to use ajp|http|https */
    char      hostname[PROXY_WORKER_MAX_ROUTE_SIZE];  /* remote backend address */
    char      hostname[PROXY_WORKER_MAX_HOSTNAME_SIZE];  /* remote backend address */
    char      route[PROXY_WORKER_MAX_ROUTE_SIZE];     /* balancing route */
    char      redirect[PROXY_WORKER_MAX_ROUTE_SIZE];  /* temporary balancing redirection route */
    char      flusher[PROXY_WORKER_MAX_SCHEME_SIZE];  /* flush provider used by mod_proxy_fdpass */
@@ -389,10 +392,10 @@ struct proxy_worker {
typedef struct {
    char      sticky_path[PROXY_BALANCER_MAX_STICKY_SIZE];     /* URL sticky session identifier */
    char      sticky[PROXY_BALANCER_MAX_STICKY_SIZE];          /* sticky session identifier */
    char      lbpname[PROXY_MAX_PROVIDER_NAME_SIZE];  /* lbmethod provider name */
    char nonce[APR_UUID_FORMATTED_LENGTH + 1];
    apr_interval_time_t timeout;  /* Timeout for waiting on free connection */
    apr_time_t      wupdated;     /* timestamp of last change to workers list */
    proxy_balancer_method *lbmethod;
    int             max_attempts;     /* Number of attempts before failing */
    int             index;      /* shm array index */
    unsigned int    sticky_force:1;   /* Disable failover for sticky sessions */
@@ -413,6 +416,7 @@ struct proxy_balancer {
    const char *name;             /* name of the load balancer */
    const char *sname;            /* filesystem safe balancer name */
    apr_time_t      wupdated;    /* timestamp of last change to workers list */
    proxy_balancer_method *lbmethod;
    apr_global_mutex_t  *gmutex; /* global lock for updating list of workers */
    apr_thread_mutex_t  *tmutex; /* Thread lock for updating shm */
    void            *context;    /* general purpose storage */
@@ -857,13 +861,13 @@ PROXY_DECLARE(char *) ap_proxy_parse_wstatus(apr_pool_t *p, proxy_worker *w);


/**
 * Create readable representation of worker status bitfield
 * Sync balancer and workers based on any updates w/i shm
 * @param b  balancer to check/update member list of
 * @param s  server rec
 * @param conf config
 * @return   APR_SUCCESS if all goes well
 */
PROXY_DECLARE(apr_status_t) ap_proxy_update_members(proxy_balancer *b, server_rec *s,
PROXY_DECLARE(apr_status_t) ap_proxy_sync_balancer(proxy_balancer *b, server_rec *s,
                                                   proxy_server_conf *conf);


+16 −11
Changes for modules/proxy/mod_proxy_balancer.c: 16 added lines, 11 removed lines.
Original line number Diff line number Diff line
@@ -331,7 +331,7 @@ static proxy_worker *find_best_worker(proxy_balancer *balancer,
        return NULL;
    }

    candidate = (*balancer->s->lbmethod->finder)(balancer, r);
    candidate = (*balancer->lbmethod->finder)(balancer, r);

    if (candidate)
        candidate->s->elected++;
@@ -470,14 +470,14 @@ static int proxy_balancer_pre_request(proxy_worker **worker,

    /* Step 3.5: Update member list for the balancer */
    /* TODO: Implement as provider! */
    ap_proxy_update_members(*balancer, r->server, conf);
    ap_proxy_sync_balancer(*balancer, r->server, conf);

    /* Step 4: find the session route */
    runtime = find_session_route(*balancer, r, &route, &sticky, url);
    if (runtime) {
        if ((*balancer)->s->lbmethod && (*balancer)->s->lbmethod->updatelbstatus) {
        if ((*balancer)->lbmethod && (*balancer)->lbmethod->updatelbstatus) {
            /* Call the LB implementation */
            (*balancer)->s->lbmethod->updatelbstatus(*balancer, runtime, r->server);
            (*balancer)->lbmethod->updatelbstatus(*balancer, runtime, r->server);
        }
        else { /* Use the default one */
            int i, total_factor = 0;
@@ -874,7 +874,7 @@ static int balancer_handler(request_rec *r)
                         "proxy: BALANCER: (%s). Lock failed for balancer_handler",
                         balancer->name);
        }
        ap_proxy_update_members(balancer, r->server, conf);
        ap_proxy_sync_balancer(balancer, r->server, conf);
        if ((rv = PROXY_THREAD_UNLOCK(balancer)) != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_ERR, rv, r->server,
                         "proxy: BALANCER: (%s). Unlock failed for balancer_handler",
@@ -975,10 +975,15 @@ static int balancer_handler(request_rec *r)
        const char *val;
        int ival;
        if ((val = apr_table_get(params, "b_lbm"))) {
            if (strlen(val) < (sizeof(bsel->s->lbpname)-1)) {
                proxy_balancer_method *lbmethod;
            lbmethod = ap_lookup_provider(PROXY_LBMETHOD, val, "0");
            if (lbmethod)
                bsel->s->lbmethod = lbmethod;
                lbmethod = ap_lookup_provider(PROXY_LBMETHOD, bsel->s->lbpname, "0");
                if (lbmethod) {
                    PROXY_STRNCPY(bsel->s->lbpname, val);
                    bsel->lbmethod = lbmethod;
                    bsel->s->wupdated = apr_time_now();
                }
            }
        }
        if ((val = apr_table_get(params, "b_tmo"))) {
            ival = atoi(val);
@@ -997,7 +1002,7 @@ static int balancer_handler(request_rec *r)
            bsel->s->sticky_force = (ival != 0);
        }
        if ((val = apr_table_get(params, "b_ss")) && *val) {
            if (strlen(val) < (PROXY_BALANCER_MAX_STICKY_SIZE-1)) {
            if (strlen(val) < (sizeof(bsel->s->sticky_path)-1)) {
                if (*val == '-' && *(val+1) == '\0')
                    *bsel->s->sticky_path = *bsel->s->sticky = '\0';
                else {
@@ -1156,7 +1161,7 @@ static int balancer_handler(request_rec *r)
                apr_time_sec(balancer->s->timeout));
            ap_rprintf(r, "<td align='center'>%d</td>\n", balancer->s->max_attempts);
            ap_rprintf(r, "<td align='center'>%s</td>\n",
                       balancer->s->lbmethod->name);
                       balancer->s->lbpname);
            ap_rputs("</table>\n<br />", r);
            ap_rputs("\n\n<table border='0' style='text-align: left;'><tr>"
                "<th>Worker URL</th>"
@@ -1244,7 +1249,7 @@ static int balancer_handler(request_rec *r)
                pname = (ap_list_provider_names_t *)provs->elts;
                for (i = 0; i < provs->nelts; i++, pname++) {
                    ap_rvputs(r,"<option value='", pname->provider_name, "'", NULL);
                    if (strcmp(pname->provider_name, bsel->s->lbmethod->name) == 0)
                    if (strcmp(pname->provider_name, bsel->s->lbpname) == 0)
                        ap_rputs(" selected ", r);
                    ap_rvputs(r, ">", pname->provider_name, "\n", NULL);
                }
+18 −4
Changes for modules/proxy/proxy_util.c: 18 added lines, 4 removed lines.
Original line number Diff line number Diff line
@@ -1381,6 +1381,7 @@ PROXY_DECLARE(char *) ap_proxy_define_balancer(apr_pool_t *p,
    (*balancer)->workers = apr_array_make(p, 5, sizeof(proxy_worker *));
    (*balancer)->gmutex = NULL;
    (*balancer)->tmutex = NULL;
    (*balancer)->lbmethod = lbmethod;

    if (do_malloc)
        bshared = malloc(sizeof(proxy_balancer_shared));
@@ -1389,8 +1390,8 @@ PROXY_DECLARE(char *) ap_proxy_define_balancer(apr_pool_t *p,

    memset(bshared, 0, sizeof(proxy_balancer_shared));

    bshared->lbmethod = lbmethod;
    bshared->was_malloced = (do_malloc != 0);
    PROXY_STRNCPY(bshared->lbpname, "byrequests");

    /* Retrieve a UUID and store the nonce for the lifetime of
     * the process. */
@@ -1410,6 +1411,7 @@ PROXY_DECLARE(apr_status_t) ap_proxy_share_balancer(proxy_balancer *balancer,
                                                    proxy_balancer_shared *shm,
                                                    int i)
{
    proxy_balancer_method *lbmethod;
    if (!shm || !balancer->s)
        return APR_EINVAL;

@@ -1418,6 +1420,10 @@ PROXY_DECLARE(apr_status_t) ap_proxy_share_balancer(proxy_balancer *balancer,
        free(balancer->s);
    balancer->s = shm;
    balancer->s->index = i;
    /* the below should always succeed */
    lbmethod = ap_lookup_provider(PROXY_LBMETHOD, balancer->s->lbpname, "0");
    if (lbmethod)
        balancer->lbmethod = lbmethod;
    return APR_SUCCESS;
}

@@ -1460,8 +1466,8 @@ PROXY_DECLARE(apr_status_t) ap_proxy_initialize_balancer(proxy_balancer *balance
        ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_EMERG, 0, s, "slotmem_attach failed");
        return APR_EGENERAL;
    }
    if (balancer->s->lbmethod && balancer->s->lbmethod->reset)
        balancer->s->lbmethod->reset(balancer, s);
    if (balancer->lbmethod && balancer->lbmethod->reset)
        balancer->lbmethod->reset(balancer, s);

    if (balancer->tmutex == NULL) {
        rv = apr_thread_mutex_create(&(balancer->tmutex), APR_THREAD_MUTEX_DEFAULT, p);
@@ -2933,17 +2939,25 @@ PROXY_DECLARE(char *) ap_proxy_parse_wstatus(apr_pool_t *p, proxy_worker *w)
    return ret;
}

PROXY_DECLARE(apr_status_t) ap_proxy_update_members(proxy_balancer *b, server_rec *s,
PROXY_DECLARE(apr_status_t) ap_proxy_sync_balancer(proxy_balancer *b, server_rec *s,
                                                    proxy_server_conf *conf)
{
    proxy_worker **workers;
    int i;
    int index;
    proxy_worker_shared *shm;
    proxy_balancer_method *lbmethod;
    ap_slotmem_provider_t *storage = b->storage;

    if (b->s->wupdated <= b->wupdated)
        return APR_SUCCESS;
    /* balancer sync */
    lbmethod = ap_lookup_provider(PROXY_LBMETHOD, b->s->lbpname, "0");
    if (lbmethod) {
	b->lbmethod = lbmethod;
    }
    /* worker sync */

    /*
     * Look thru the list of workers in shm
     * and see which one(s) we are lacking...