proxy_conn_rec *conn; /* Single connection for prefork mpm */
};
-/* Keep below in sync with proxy_util.c! */
/* worker status bits */
+/*
+ * NOTE: Keep up-to-date w/ proxy_wstat_tbl[]
+ * in proxy_util.c !
+ */
#define PROXY_WORKER_INITIALIZED 0x0001
#define PROXY_WORKER_IGNORE_ERRORS 0x0002
#define PROXY_WORKER_DRAIN 0x0004
#define PROXY_WORKER_IN_ERROR 0x0080
#define PROXY_WORKER_HOT_STANDBY 0x0100
#define PROXY_WORKER_FREE 0x0200
+#define PROXY_WORKER_HC_FAIL 0x0400
/* worker status flags */
#define PROXY_WORKER_INITIALIZED_FLAG 'O'
#define PROXY_WORKER_IN_ERROR_FLAG 'E'
#define PROXY_WORKER_HOT_STANDBY_FLAG 'H'
#define PROXY_WORKER_FREE_FLAG 'F'
+#define PROXY_WORKER_HC_FAIL_FLAG '#'
#define PROXY_WORKER_NOT_USABLE_BITMAP ( PROXY_WORKER_IN_SHUTDOWN | \
-PROXY_WORKER_DISABLED | PROXY_WORKER_STOPPED | PROXY_WORKER_IN_ERROR )
+PROXY_WORKER_DISABLED | PROXY_WORKER_STOPPED | PROXY_WORKER_IN_ERROR | \
+PROXY_WORKER_HC_FAIL )
/* NOTE: these check the shared status */
#define PROXY_WORKER_IS_INITIALIZED(f) ( (f)->s->status & PROXY_WORKER_INITIALIZED )
int index; /* shm array index */
int method; /* method to use for health check */
int passes; /* number of successes for check to pass */
- int fails; /* number of failures for check to fail */
+ int pcount; /* current count of passes */
+ int fails; /* number of failures for check to fail */
+ int fcount; /* current count of failures */
proxy_hashes hash; /* hash of worker name */
unsigned int status; /* worker status bitfield */
enum {
#include "mod_proxy.h"
#include "mod_watchdog.h"
+#include "ap_slotmem.h"
+
module AP_MODULE_DECLARE_DATA proxy_hcheck_module;
"NULL", "OPTIONS", "HEAD", "GET", "POST", "CPING"
};
-typedef struct hcheck_template_t {
+typedef struct hc_template_t {
char *name;
int method;
int passes;
int fails;
apr_interval_time_t interval;
char *hurl;
-} hcheck_template_t;
+} hc_template_t;
static apr_pool_t *ptemplate = NULL;
static apr_array_header_t *templates = NULL;
void *tmp)
{
int ival;
- hcheck_template_t *ctx;
+ hc_template_t *ctx;
if (!worker && !tmp) {
return "Bad call to set_worker_hc_param()";
}
- ctx = (hcheck_template_t *)tmp;
+ ctx = (hc_template_t *)tmp;
if (!strcasecmp(key, "hcheck")) {
- hcheck_template_t *template;
- template = (hcheck_template_t *)templates->elts;
+ hc_template_t *template;
+ template = (hc_template_t *)templates->elts;
for (ival = 0; ival < templates->nelts; ival++, template++) {
if (!ap_casecmpstr(template->name, val)) {
worker->s->method = template->method;
{
char *name = NULL;
char *word, *val;
- hcheck_template_t template;
- hcheck_template_t *tpush;
+ hc_template_t template;
+ hc_template_t *tpush;
const char *err = ap_check_cmd_context(cmd, NOT_IN_HTACCESS);
if (err)
return err;
if (err)
return apr_pstrcat(cmd->temp_pool, "HCheckTemplate: ", err, " ", word, "=", val, "; ", name, NULL);
/* No error means we have a valid template */
- tpush = (hcheck_template_t *)apr_array_push(templates);
- memcpy(tpush, &template, sizeof(hcheck_template_t));
+ tpush = (hc_template_t *)apr_array_push(templates);
+ memcpy(tpush, &template, sizeof(hc_template_t));
}
return NULL;
apr_pool_create(&ptemplate, p);
}
if (!templates) {
- templates = apr_array_make(ptemplate, 10, sizeof(hcheck_template_t));
+ templates = apr_array_make(ptemplate, 10, sizeof(hc_template_t));
}
return OK;
}
static void hc_register_hooks(apr_pool_t *p)
{
- static const char *const runAfter[] = { "mod_watchdog.c", NULL};
+ static const char *const runAfter[] = { "mod_watchdog.c", "mod_proxy_balancer.c", NULL};
APR_REGISTER_OPTIONAL_FN(set_worker_hc_param);
ap_hook_pre_config(hc_pre_config, NULL, NULL, APR_HOOK_LAST);
ap_hook_post_config(hc_post_config, NULL, runAfter, APR_HOOK_LAST);
const char *proxy_auth; /* Proxy authorization */
} forward_info;
-/* Keep synced with mod_proxy.h! */
-static struct wstat {
+static struct proxy_wstat {
unsigned int bit;
char flag;
const char *name;
-} wstat_tbl[] = {
+} proxy_wstat_tbl[] = {
{PROXY_WORKER_INITIALIZED, PROXY_WORKER_INITIALIZED_FLAG, "Init "},
{PROXY_WORKER_IGNORE_ERRORS, PROXY_WORKER_IGNORE_ERRORS_FLAG, "Ign "},
{PROXY_WORKER_DRAIN, PROXY_WORKER_DRAIN_FLAG, "Drn "},
+ {PROXY_WORKER_GENERIC, PROXY_WORKER_GENERIC_FLAG, "Gen "},
{PROXY_WORKER_IN_SHUTDOWN, PROXY_WORKER_IN_SHUTDOWN_FLAG, "Shut "},
{PROXY_WORKER_DISABLED, PROXY_WORKER_DISABLED_FLAG, "Dis "},
{PROXY_WORKER_STOPPED, PROXY_WORKER_STOPPED_FLAG, "Stop "},
{PROXY_WORKER_IN_ERROR, PROXY_WORKER_IN_ERROR_FLAG, "Err "},
{PROXY_WORKER_HOT_STANDBY, PROXY_WORKER_HOT_STANDBY_FLAG, "Stby "},
{PROXY_WORKER_FREE, PROXY_WORKER_FREE_FLAG, "Free "},
+ {PROXY_WORKER_HC_FAIL, PROXY_WORKER_HC_FAIL_FLAG, "HcFl "},
{0x0, '\0', NULL}
};
{
unsigned int *status = &w->s->status;
char flag = toupper(c);
- struct wstat *pwt = wstat_tbl;
+ struct proxy_wstat *pwt = proxy_wstat_tbl;
while (pwt->bit) {
if (flag == pwt->flag) {
if (set)
{
char *ret = "";
unsigned int status = w->s->status;
- struct wstat *pwt = wstat_tbl;
+ struct proxy_wstat *pwt = proxy_wstat_tbl;
while (pwt->bit) {
if (status & pwt->bit)
ret = apr_pstrcat(p, ret, pwt->name, NULL);
pwt++;
}
+ if (!*ret) {
+ ret = "??? ";
+ }
if (PROXY_WORKER_IS_USABLE(w))
ret = apr_pstrcat(p, ret, "Ok ", NULL);
return ret;