Skip to content

Commit

Permalink
Merge pull request #304 from jajik/issue-301
Browse files Browse the repository at this point in the history
Add ProxyHCTemplate support to mod_lbmethod_cluster
  • Loading branch information
jajik authored Dec 13, 2024
2 parents 1893118 + 8646abb commit bce1a30
Show file tree
Hide file tree
Showing 9 changed files with 213 additions and 64 deletions.
55 changes: 45 additions & 10 deletions native/balancers/mod_lbmethod_cluster.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
#include "mod_watchdog.h"
#include "common.h"


#define LB_CLUSTER_WATHCHDOG_NAME ("_lb_cluster_")
static ap_watchdog_t *watchdog;

Expand All @@ -16,6 +15,9 @@ static struct context_storage_method *context_storage = NULL;
static struct balancer_storage_method *balancer_storage = NULL;
static struct domain_storage_method *domain_storage = NULL;

static apr_table_t *proxyhctemplate;
static void (*set_proxyhctemplate_f)(apr_pool_t *, apr_table_t *) = NULL;

static int use_alias = 0; /* 1 : Compare Alias with server_name */
static int use_nocanon = 0;
static apr_time_t lbstatus_recalc_time =
Expand Down Expand Up @@ -91,7 +93,9 @@ static proxy_worker *find_best(proxy_balancer *balancer, request_rec *r)
node_table = read_node_table(r->pool, node_storage, 0);
}

node_storage->lock_nodes();
mycandidate = internal_find_best_byrequests(r, balancer, vhost_table, context_table, node_table);
node_storage->unlock_nodes();

return mycandidate;
}
Expand Down Expand Up @@ -319,7 +323,9 @@ static apr_status_t mc_watchdog_callback(int state, void *data, apr_pool_t *pool
}

/* cleanup removed node in shared memory */
node_storage->lock_nodes();
remove_removed_node(s, pool, now, node_table);
node_storage->unlock_nodes();
}
break;

Expand All @@ -339,29 +345,38 @@ static int lbmethod_cluster_post_config(apr_pool_t *p, apr_pool_t *plog, apr_poo

node_storage = ap_lookup_provider("manager", "shared", "0");
if (node_storage == NULL) {
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, "proxy_cluster_post_config: Can't find mod_manager for nodes");
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, "lbmethod_cluster_post_config: Can't find mod_manager for nodes");
return !OK;
}
host_storage = ap_lookup_provider("manager", "shared", "1");
if (host_storage == NULL) {
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, "proxy_cluster_post_config: Can't find mod_manager for hosts");
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, "lbmethod_cluster_post_config: Can't find mod_manager for hosts");
return !OK;
}
context_storage = ap_lookup_provider("manager", "shared", "2");
if (context_storage == NULL) {
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, "proxy_cluster_post_config: Can't find mod_manager for contexts");
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s,
"lbmethod_cluster_post_config: Can't find mod_manager for contexts");
return !OK;
}
balancer_storage = ap_lookup_provider("manager", "shared", "3");
if (balancer_storage == NULL) {
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, "proxy_cluster_post_config: Can't find mod_manager for balancers");
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s,
"lbmethod_cluster_post_config: Can't find mod_manager for balancers");
return !OK;
}
domain_storage = ap_lookup_provider("manager", "shared", "5");
if (domain_storage == NULL) {
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, "proxy_cluster_post_config: Can't find mod_manager for domains");
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, "lbmethod_cluster_post_config: Can't find mod_manager for domains");
return !OK;
}
set_proxyhctemplate_f = ap_lookup_provider("manager", "shared", "6");
if (set_proxyhctemplate_f == NULL) {
ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
"lbmethod_cluster_post_config: Can't find mod_manager for set_proxyhctemplate function");
} else if (!apr_is_empty_table(proxyhctemplate)) {
set_proxyhctemplate_f(p, proxyhctemplate);
}

/* Add version information */
ap_add_version_component(p, MOD_CLUSTER_EXPOSED_VERSION);
Expand All @@ -375,19 +390,19 @@ static int lbmethod_cluster_post_config(apr_pool_t *p, apr_pool_t *plog, apr_poo
mc_watchdog_register_callback = APR_RETRIEVE_OPTIONAL_FN(ap_watchdog_register_callback);
if (!mc_watchdog_get_instance || !mc_watchdog_register_callback) {
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s,
APLOGNO(03262) "proxy_cluster_post_config: mod_watchdog is required");
APLOGNO(03262) "lbmethod_cluster_post_config: mod_watchdog is required");
return !OK;
}
if (mc_watchdog_get_instance(&watchdog, LB_CLUSTER_WATHCHDOG_NAME, 0, 1, p)) {
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s,
APLOGNO(03263) "proxy_cluster_post_config: Failed to create watchdog instance (%s)",
APLOGNO(03263) "lbmethod_cluster_post_config: Failed to create watchdog instance (%s)",
LB_CLUSTER_WATHCHDOG_NAME);
return !OK;
}
while (s) {
if (mc_watchdog_register_callback(watchdog, AP_WD_TM_SLICE, s, mc_watchdog_callback)) {
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s,
APLOGNO(03264) "proxy_cluster_post_config: Failed to register watchdog callback (%s)",
APLOGNO(03264) "lbmethod_cluster_post_config: Failed to register watchdog callback (%s)",
LB_CLUSTER_WATHCHDOG_NAME);
return !OK;
}
Expand All @@ -405,10 +420,30 @@ static const char *cmd_nocanon(cmd_parms *parms, void *mconfig, int on)
return NULL;
}

static const char *cmd_proxyhctemplate(cmd_parms *cmd, void *dummy, const char *arg)
{
const char *err = NULL;
(void)dummy;

if (!proxyhctemplate) {
proxyhctemplate = apr_table_make(cmd->pool, 8);
}

err = parse_proxyhctemplate_params(cmd->pool, arg, proxyhctemplate);
if (err != NULL) {
return err;
}
return NULL;
}

static const command_rec lbmethod_cmds[] = {
AP_INIT_FLAG("UseNocanon", cmd_nocanon, NULL, OR_ALL,
"UseNocanon - When no ProxyPass or ProxyMatch for the URL, passes the URL path \"raw\" to the backend "
"(Default: Off)")};
"(Default: Off)"),
AP_INIT_RAW_ARGS(
"ModProxyClusterHCTemplate", cmd_proxyhctemplate, NULL, OR_ALL,
"ModProxyClusterHCTemplate - Set of health check parameters to use with mod_lbmethod_cluster workers."),
{NULL}};

static void register_hooks(apr_pool_t *p)
{
Expand Down
16 changes: 16 additions & 0 deletions native/common/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -670,3 +670,19 @@ const node_context *context_host_ok(request_rec *r, const proxy_balancer *balanc

return best->node != -1 ? best : NULL;
}

const char *parse_proxyhctemplate_params(apr_pool_t *pool, const char *arg, apr_table_t *params)
{
while (*arg) {
char *key, *val;
key = ap_getword_conf(pool, &arg);
val = strchr(key, '=');
if (!val) {
return "Invalid ProxyHCTemplate parameter. Parameter must be in the form 'key=value'";
}
*val++ = '\0';

apr_table_add(params, key, val);
}
return NULL;
}
6 changes: 6 additions & 0 deletions native/include/balancer.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,4 +143,10 @@ struct balancer_storage_method
*/
int (*get_max_size_balancer)(void);
};

/**
* Helper function for translating hcheck template parameters to corresponding balancer parameters
*/
const char *translate_balancer_params(const char *param);

#endif /*BALANCER_H*/
8 changes: 6 additions & 2 deletions native/include/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
* Common routines
*/


#include "mod_proxy_cluster.h"


Expand All @@ -17,7 +16,6 @@ struct counter
int *values;
};


/**
* Read the virtual host table from shared memory
* @param pool pool to use for memory allocation
Expand Down Expand Up @@ -222,3 +220,9 @@ apr_status_t loc_get_id(void *mem, void *data, apr_pool_t *pool);
const node_context *context_host_ok(request_rec *r, const proxy_balancer *balancer, int node, int use_alias,
const proxy_vhost_table *vhost_table, const proxy_context_table *context_table,
const proxy_node_table *node_table);

/**
* Parse ProxyHCTemplate parameters from @param arg into @param params using @param pool for allocations
* @return error message or NULL if everything went well
*/
const char *parse_proxyhctemplate_params(apr_pool_t *pool, const char *arg, apr_table_t *params);
24 changes: 24 additions & 0 deletions native/mod_manager/balancer.c
Original file line number Diff line number Diff line change
Expand Up @@ -174,3 +174,27 @@ mem_t *create_mem_balancer(char *string, unsigned *num, int persist, apr_pool_t
{
return create_attach_mem_balancer(string, num, persist, 1, p, storage);
}

const char *translate_balancer_params(const char *param)
{
if (strcasecmp(param, "hcinterval") == 0) {
return "w_hi";
}
if (strcasecmp(param, "hcpasses") == 0) {
return "w_hp";
}
if (strcasecmp(param, "hcfails") == 0) {
return "w_hf";
}
if (strcasecmp(param, "hcmethod") == 0) {
return "w_hm";
}
if (strcasecmp(param, "hcuri") == 0) {
return "w_hu";
}
if (strcasecmp(param, "hcexpr") == 0) {
return "w_he";
}

return NULL;
}
36 changes: 32 additions & 4 deletions native/mod_manager/mod_manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,13 @@ static mem_t *hoststatsmem = NULL;
static mem_t *balancerstatsmem = NULL;
static mem_t *sessionidstatsmem = NULL;
static mem_t *domainstatsmem = NULL;
/* Used for HCExpr templates with lbmethod_cluster */
static apr_table_t *proxyhctemplate = NULL;

static void set_proxyhctemplate(apr_pool_t *p, apr_table_t *t)
{
proxyhctemplate = apr_table_overlay(p, t, proxyhctemplate);
}

static slotmem_storage_method *storage = NULL;
static balancer_method *balancerhandler = NULL;
Expand Down Expand Up @@ -540,6 +547,7 @@ static int manager_pre_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *p
(void)ptemp;
ap_mutex_register(pconf, node_mutex_type, NULL, APR_LOCK_DEFAULT, 0);
ap_mutex_register(pconf, context_mutex_type, NULL, APR_LOCK_DEFAULT, 0);
proxyhctemplate = apr_table_make(plog, 1);
return OK;
}

Expand Down Expand Up @@ -910,6 +918,11 @@ static int is_same_worker_existing(const request_rec *r, const nodeinfo_t *node)
static apr_status_t mod_manager_manage_worker(request_rec *r, const nodeinfo_t *node, const balancerinfo_t *bal)
{
apr_table_t *params;
apr_status_t rv;
int i;
const apr_array_header_t *h;
const apr_table_entry_t *entries;

params = apr_table_make(r->pool, 10);
/* balancer */
apr_table_set(params, "b", node->mess.balancer);
Expand All @@ -922,7 +935,10 @@ static apr_status_t mod_manager_manage_worker(request_rec *r, const nodeinfo_t *
apr_table_set(params, "b_wyes", "1");
apr_table_set(params, "b_nwrkr",
apr_pstrcat(r->pool, node->mess.Type, "://", node->mess.Host, ":", node->mess.Port, NULL));
balancer_manage(r, params);
rv = balancer_manage(r, params);
if (rv != APR_SUCCESS) {
return rv;
}
apr_table_clear(params);

/* now process the worker */
Expand All @@ -938,6 +954,17 @@ static apr_status_t mod_manager_manage_worker(request_rec *r, const nodeinfo_t *

/* Use 10 sec for the moment, the idea is to adjust it with the STATUS frequency */
apr_table_set(params, "w_hi", "10000");

h = apr_table_elts(proxyhctemplate);
entries = (const apr_table_entry_t *)h->elts;

for (i = 0; i < h->nelts; i++) {
const char *key = translate_balancer_params(entries[i].key);
if (key != NULL) {
apr_table_set(params, key, entries[i].val);
}
}

return balancer_manage(r, params);
}

Expand Down Expand Up @@ -1548,14 +1575,14 @@ static char *process_config(request_rec *r, char **ptr, int *errtype)
/* Insert the Alias and corresponding Context */
phost = vhost;
if (phost->host == NULL && phost->context == NULL) {
loc_unlock_nodes();
/* if using mod_balancer create or update the worker */
if (balancer_manage) {
apr_status_t rv = mod_manager_manage_worker(r, &nodeinfo, &balancerinfo);
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "process_config: balancer-manager returned %d", rv);
} else {
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "process_config: NO balancer-manager");
}
loc_unlock_nodes();
return NULL; /* Alias and Context missing */
}
while (phost) {
Expand All @@ -1570,7 +1597,6 @@ static char *process_config(request_rec *r, char **ptr, int *errtype)
phost = phost->next;
vid++;
}
loc_unlock_nodes();

/* if using mod_balancer create or update the worker */
if (balancer_manage) {
Expand All @@ -1579,6 +1605,7 @@ static char *process_config(request_rec *r, char **ptr, int *errtype)
} else {
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "process_config: NO balancer-manager");
}
loc_unlock_nodes();

ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "process_config: Done");

Expand Down Expand Up @@ -2157,7 +2184,7 @@ static char *process_appl_cmd(request_rec *r, char **ptr, int status, int *errty
if (vhost->host != NULL) {
int start = 0;
i = 0;
while (host == NULL && i + start < strlen(vhost->host)) {
while (host == NULL && (unsigned)(i + start) < strlen(vhost->host)) {
while (vhost->host[start + i] != ',' && vhost->host[start + i] != '\0') {
i++;
}
Expand Down Expand Up @@ -3935,6 +3962,7 @@ static void manager_hooks(apr_pool_t *p)
ap_register_provider(p, "manager", "shared", "3", &balancer_storage);
ap_register_provider(p, "manager", "shared", "4", &sessionid_storage);
ap_register_provider(p, "manager", "shared", "5", &domain_storage);
ap_register_provider(p, "manager", "shared", "6", &set_proxyhctemplate);
}

/*
Expand Down
Loading

0 comments on commit bce1a30

Please sign in to comment.