MINOR: proxy: Introduce proxy flags to replace disabled bitfield

This change is required to support TCP/HTTP rules in defaults sections. The
'disabled' bitfield in the proxy structure, used to know if a proxy is
disabled or stopped, is replaced a generic bitfield named 'flags'.

PR_DISABLED and PR_STOPPED flags are renamed to PR_FL_DISABLED and
PR_FL_STOPPED respectively. In addition, everywhere there is a test to know
if a proxy is disabled or stopped, there is now a bitwise AND operation on
PR_FL_DISABLED and/or PR_FL_STOPPED flags.
This commit is contained in:
Christopher Faulet 2021-10-06 14:24:19 +02:00
parent 647a61cc4b
commit dfd10ab5ee
19 changed files with 54 additions and 54 deletions

View File

@ -613,7 +613,7 @@ static int promex_dump_front_metrics(struct appctx *appctx, struct htx *htx)
labels[0].value = ist2(px->id, strlen(px->id));
/* skip the disabled proxies, global frontend and non-networked ones */
if (px->disabled || px->uuid <= 0 || !(px->cap & PR_CAP_FE))
if ((px->flags & PR_FL_DISABLED) || px->uuid <= 0 || !(px->cap & PR_CAP_FE))
goto next_px;
if (!stats_fill_fe_stats(px, stats, ST_F_TOTAL_FIELDS, &(appctx->st2)))
@ -621,7 +621,7 @@ static int promex_dump_front_metrics(struct appctx *appctx, struct htx *htx)
switch (appctx->st2) {
case ST_F_STATUS:
state = !px->disabled;
state = !(px->flags & PR_FL_STOPPED);
for (; appctx->ctx.stats.st_code < PROMEX_FRONT_STATE_COUNT; appctx->ctx.stats.st_code++) {
labels[1].name = ist("state");
labels[1].value = promex_front_st[appctx->ctx.stats.st_code];
@ -714,7 +714,7 @@ static int promex_dump_listener_metrics(struct appctx *appctx, struct htx *htx)
labels[0].value = ist2(px->id, strlen(px->id));
/* skip the disabled proxies, global frontend and non-networked ones */
if (px->disabled || px->uuid <= 0 || !(px->cap & PR_CAP_FE))
if ((px->flags & PR_FL_DISABLED) || px->uuid <= 0 || !(px->cap & PR_CAP_FE))
goto next_px;
li = appctx->ctx.stats.obj2;
@ -804,7 +804,7 @@ static int promex_dump_back_metrics(struct appctx *appctx, struct htx *htx)
labels[0].value = ist2(px->id, strlen(px->id));
/* skip the disabled proxies, global frontend and non-networked ones */
if (px->disabled || px->uuid <= 0 || !(px->cap & PR_CAP_BE))
if ((px->flags & PR_FL_DISABLED) || px->uuid <= 0 || !(px->cap & PR_CAP_BE))
goto next_px;
if (!stats_fill_be_stats(px, 0, stats, ST_F_TOTAL_FIELDS, &(appctx->st2)))
@ -937,7 +937,7 @@ static int promex_dump_srv_metrics(struct appctx *appctx, struct htx *htx)
labels[0].value = ist2(px->id, strlen(px->id));
/* skip the disabled proxies, global frontend and non-networked ones */
if (px->disabled || px->uuid <= 0 || !(px->cap & PR_CAP_BE))
if ((px->flags & PR_FL_DISABLED) || px->uuid <= 0 || !(px->cap & PR_CAP_BE))
goto next_px;
while (appctx->ctx.stats.obj2) {

View File

@ -52,7 +52,7 @@ int be_lastsession(const struct proxy *be);
/* Returns number of usable servers in backend */
static inline int be_usable_srv(struct proxy *be)
{
if (be->disabled)
if (be->flags & (PR_FL_DISABLED|PR_FL_STOPPED))
return 0;
else if (be->srv_act)
return be->srv_act;

View File

@ -200,9 +200,9 @@ enum PR_SRV_STATE_FILE {
#define PR_RE_EARLY_ERROR 0x00010000 /* Retry if we failed at sending early data */
#define PR_RE_JUNK_REQUEST 0x00020000 /* We received an incomplete or garbage response */
/* disabled state */
#define PR_DISABLED 0x1 /* The proxy was disabled in the configuration (not at runtime) */
#define PR_STOPPED 0x2 /* The proxy was stopped */
/* Proxy flags */
#define PR_FL_DISABLED 0x01 /* The proxy was disabled in the configuration (not at runtime) */
#define PR_FL_STOPPED 0x02 /* The proxy was stopped */
struct stream;
@ -258,7 +258,7 @@ struct error_snapshot {
struct proxy {
enum obj_type obj_type; /* object type == OBJ_TYPE_PROXY */
char disabled; /* bit field PR_DISABLED | PR_STOPPED */
char flags; /* bit field PR_FL_* */
enum pr_mode mode; /* mode = PR_MODE_TCP, PR_MODE_HTTP, ... */
char cap; /* supported capabilities (PR_CAP_*) */
unsigned int maxconn; /* max # of active streams on the frontend */

View File

@ -595,12 +595,12 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
else if (strcmp(args[0], "disabled") == 0) { /* disables this proxy */
if (alertif_too_many_args(0, file, linenum, args, &err_code))
goto out;
curproxy->disabled |= PR_DISABLED;
curproxy->flags |= PR_FL_DISABLED;
}
else if (strcmp(args[0], "enabled") == 0) { /* enables this proxy (used to revert a disabled default) */
if (alertif_too_many_args(0, file, linenum, args, &err_code))
goto out;
curproxy->disabled = 0;
curproxy->flags &= ~PR_FL_DISABLED;
}
else if (strcmp(args[0], "bind-process") == 0) { /* enable this proxy only on some processes */
int cur_arg = 1;

View File

@ -1019,7 +1019,7 @@ int cfg_parse_peers(const char *file, int linenum, char **args, int kwm)
stktables_list = t;
}
else if (strcmp(args[0], "disabled") == 0) { /* disables this peers section */
curpeers->disabled |= PR_DISABLED;
curpeers->disabled |= PR_FL_DISABLED;
}
else if (strcmp(args[0], "enabled") == 0) { /* enables this peers section (used to revert a disabled default) */
curpeers->disabled = 0;
@ -2502,7 +2502,7 @@ int check_config_validity()
if (curproxy->uuid >= 0)
next_pxid++;
if (curproxy->disabled) {
if (curproxy->flags & PR_FL_DISABLED) {
/* ensure we don't keep listeners uselessly bound. We
* can't disable their listeners yet (fdtab not
* allocated yet) but let's skip them.
@ -3962,7 +3962,7 @@ int check_config_validity()
* other proxies.
*/
for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
if (curproxy->disabled || !curproxy->table)
if ((curproxy->flags & PR_FL_DISABLED) || !curproxy->table)
continue;
if (!stktable_init(curproxy->table)) {

View File

@ -1117,7 +1117,7 @@ struct task *process_chk_conn(struct task *t, void *context, unsigned int state)
* is disabled.
*/
if (((check->state & (CHK_ST_ENABLED | CHK_ST_PAUSED)) != CHK_ST_ENABLED) ||
proxy->disabled) {
(proxy->flags & (PR_FL_DISABLED|PR_FL_STOPPED))) {
TRACE_STATE("health-check paused or disabled", CHK_EV_TASK_WAKE, check);
goto reschedule;
}

View File

@ -494,7 +494,7 @@ struct task *process_chk_proc(struct task *t, void *context, unsigned int state)
* is disabled.
*/
if (((check->state & (CHK_ST_ENABLED | CHK_ST_PAUSED)) != CHK_ST_ENABLED) ||
s->proxy->disabled)
(s->proxy->flags & (PR_FL_DISABLED|PR_FL_STOPPED)))
goto reschedule;
/* we'll initiate a new check */

View File

@ -292,7 +292,7 @@ flt_init_all()
int err_code = ERR_NONE;
for (px = proxies_list; px; px = px->next) {
if (px->disabled) {
if (px->flags & (PR_FL_DISABLED|PR_FL_STOPPED)) {
flt_deinit(px);
continue;
}
@ -315,7 +315,7 @@ flt_init_all_per_thread()
int err_code = 0;
for (px = proxies_list; px; px = px->next) {
if (px->disabled)
if (px->flags & (PR_FL_DISABLED|PR_FL_STOPPED))
continue;
err_code = flt_init_per_thread(px);

View File

@ -1999,7 +1999,7 @@ static void init(int argc, char **argv)
struct post_proxy_check_fct *ppcf;
struct post_server_check_fct *pscf;
if (px->disabled)
if (px->flags & (PR_FL_DISABLED|PR_FL_STOPPED))
continue;
list_for_each_entry(pscf, &post_server_check_list, list) {
@ -2061,13 +2061,13 @@ static void init(int argc, char **argv)
break;
for (px = proxies_list; px; px = px->next)
if (!px->disabled && px->li_all)
if (!(px->flags & (PR_FL_DISABLED|PR_FL_STOPPED)) && px->li_all)
break;
if (!px) {
/* We may only have log-forward section */
for (px = cfg_log_forward; px; px = px->next)
if (!px->disabled && px->li_all)
if (!(px->flags & (PR_FL_DISABLED|PR_FL_STOPPED)) && px->li_all)
break;
}
@ -2401,7 +2401,7 @@ static void init(int argc, char **argv)
/* stop disabled proxies */
for (px = proxies_list; px; px = px->next) {
if (px->disabled)
if (px->flags & (PR_FL_DISABLED|PR_FL_STOPPED))
stop_proxy(px);
}

View File

@ -3088,7 +3088,7 @@ static int fcgi_process(struct fcgi_conn *fconn)
}
fcgi_send(fconn);
if (unlikely(fconn->proxy->disabled)) {
if (unlikely(fconn->proxy->flags & (PR_FL_DISABLED|PR_FL_STOPPED))) {
/* frontend is stopping, reload likely in progress, let's try
* to announce a graceful shutdown if not yet done. We don't
* care if it fails, it will be tried again later.

View File

@ -1023,7 +1023,7 @@ static void h1_set_cli_conn_mode(struct h1s *h1s, struct h1m *h1m)
}
/* If KAL, check if the frontend is stopping. If yes, switch in CLO mode */
if (h1s->flags & H1S_F_WANT_KAL && fe->disabled) {
if (h1s->flags & H1S_F_WANT_KAL && (fe->flags & (PR_FL_DISABLED|PR_FL_STOPPED))) {
h1s->flags = (h1s->flags & ~H1S_F_WANT_MSK) | H1S_F_WANT_CLO;
TRACE_STATE("stopping, set close mode", H1_EV_RX_DATA|H1_EV_RX_HDRS|H1_EV_TX_DATA|H1_EV_TX_HDRS, h1s->h1c->conn, h1s);
}
@ -1087,7 +1087,7 @@ static void h1_set_srv_conn_mode(struct h1s *h1s, struct h1m *h1m)
}
/* If KAL, check if the backend is stopping. If yes, switch in CLO mode */
if (h1s->flags & H1S_F_WANT_KAL && be->disabled) {
if (h1s->flags & H1S_F_WANT_KAL && (be->flags & (PR_FL_DISABLED|PR_FL_STOPPED))) {
h1s->flags = (h1s->flags & ~H1S_F_WANT_MSK) | H1S_F_WANT_CLO;
TRACE_STATE("stopping, set close mode", H1_EV_RX_DATA|H1_EV_RX_HDRS|H1_EV_TX_DATA|H1_EV_TX_HDRS, h1s->h1c->conn, h1s);
}
@ -2841,7 +2841,7 @@ static int h1_process(struct h1c * h1c)
* Release idling front connection if this is the case.
*/
if (!(h1c->flags & H1C_F_IS_BACK)) {
if (unlikely(h1c->px->disabled)) {
if (unlikely(h1c->px->flags & (PR_FL_DISABLED|PR_FL_STOPPED))) {
if (h1c->flags & H1C_F_WAIT_NEXT_REQ)
goto release;
}

View File

@ -3925,7 +3925,7 @@ static int h2_process(struct h2c *h2c)
}
h2_send(h2c);
if (unlikely(h2c->proxy->disabled) && !(h2c->flags & H2_CF_IS_BACK)) {
if (unlikely(h2c->proxy->flags & (PR_FL_DISABLED|PR_FL_STOPPED)) && !(h2c->flags & H2_CF_IS_BACK)) {
/* frontend is stopping, reload likely in progress, let's try
* to announce a graceful shutdown if not yet done. We don't
* care if it fails, it will be tried again later.

View File

@ -443,7 +443,7 @@ void mworker_cleanlisteners()
}
/* if the proxy shouldn't be in the master, we stop it */
if (!listen_in_master)
curproxy->disabled |= PR_DISABLED;
curproxy->flags |= PR_FL_DISABLED;
}
}

View File

@ -1364,7 +1364,7 @@ void init_new_proxy(struct proxy *p)
void proxy_preset_defaults(struct proxy *defproxy)
{
defproxy->mode = PR_MODE_TCP;
defproxy->disabled = 0;
defproxy->flags = 0;
if (!(defproxy->cap & PR_CAP_INT)) {
defproxy->maxconn = cfg_maxpconn;
defproxy->conn_retries = CONN_RETRIES;
@ -1532,7 +1532,7 @@ static int proxy_defproxy_cpy(struct proxy *curproxy, const struct proxy *defpro
/* set default values from the specified default proxy */
memcpy(&curproxy->defsrv, &defproxy->defsrv, sizeof(curproxy->defsrv));
curproxy->disabled = defproxy->disabled;
curproxy->flags = defproxy->flags;
curproxy->options = defproxy->options;
curproxy->options2 = defproxy->options2;
curproxy->no_options = defproxy->no_options;
@ -1811,19 +1811,19 @@ struct proxy *parse_new_proxy(const char *name, unsigned int cap,
}
/* to be called under the proxy lock after stopping some listeners. This will
* automatically update the p->disabled flag after stopping the last one, and
* automatically update the p->flags flag after stopping the last one, and
* will emit a log indicating the proxy's condition. The function is idempotent
* so that it will not emit multiple logs; a proxy will be disabled only once.
*/
void proxy_cond_disable(struct proxy *p)
{
if (p->disabled)
if (p->flags & (PR_FL_DISABLED|PR_FL_STOPPED))
return;
if (p->li_ready + p->li_paused > 0)
return;
p->disabled |= PR_STOPPED;
p->flags |= PR_FL_STOPPED;
/* Note: syslog proxies use their own loggers so while it's somewhat OK
* to report them being stopped as a warning, we must not spam their log
@ -1863,7 +1863,7 @@ struct task *manage_proxy(struct task *t, void *context, unsigned int state)
*/
/* first, let's check if we need to stop the proxy */
if (unlikely(stopping && !p->disabled)) {
if (unlikely(stopping && !(p->flags & (PR_FL_DISABLED|PR_FL_STOPPED)))) {
int t;
t = tick_remain(now_ms, p->stop_time);
if (t == 0) {
@ -1883,7 +1883,7 @@ struct task *manage_proxy(struct task *t, void *context, unsigned int state)
* be in neither list. Any entry being dumped will have ref_cnt > 0.
* However we protect tables that are being synced to peers.
*/
if (unlikely(stopping && p->disabled && p->table && p->table->current)) {
if (unlikely(stopping && (p->flags & (PR_FL_DISABLED|PR_FL_STOPPED)) && p->table && p->table->current)) {
if (!p->table->refcnt) {
/* !table->refcnt means there
@ -2103,7 +2103,7 @@ int pause_proxy(struct proxy *p)
{
struct listener *l;
if (!(p->cap & PR_CAP_FE) || p->disabled || !p->li_ready)
if (!(p->cap & PR_CAP_FE) || (p->flags & (PR_FL_DISABLED|PR_FL_STOPPED)) || !p->li_ready)
return 1;
list_for_each_entry(l, &p->conf.listeners, by_fe)
@ -2122,7 +2122,7 @@ int pause_proxy(struct proxy *p)
* to be called when going down in order to release the ports so that another
* process may bind to them. It must also be called on disabled proxies at the
* end of start-up. If all listeners are closed, the proxy is set to the
* PR_STSTOPPED state. The function takes the proxy's lock so it's safe to
* PR_STOPPED state. The function takes the proxy's lock so it's safe to
* call from multiple places.
*/
void stop_proxy(struct proxy *p)
@ -2134,9 +2134,9 @@ void stop_proxy(struct proxy *p)
list_for_each_entry(l, &p->conf.listeners, by_fe)
stop_listener(l, 1, 0, 0);
if (!p->disabled && !p->li_ready) {
if (!(p->flags & (PR_FL_DISABLED|PR_FL_STOPPED)) && !p->li_ready) {
/* might be just a backend */
p->disabled |= PR_STOPPED;
p->flags |= PR_FL_STOPPED;
}
HA_RWLOCK_WRUNLOCK(PROXY_LOCK, &p->lock);
@ -2152,7 +2152,7 @@ int resume_proxy(struct proxy *p)
struct listener *l;
int fail;
if (p->disabled || !p->li_paused)
if ((p->flags & (PR_FL_DISABLED|PR_FL_STOPPED)) || !p->li_paused)
return 1;
fail = 0;
@ -2372,7 +2372,7 @@ void proxy_adjust_all_maxconn()
struct switching_rule *swrule1, *swrule2;
for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
if (curproxy->disabled)
if (curproxy->flags & (PR_FL_DISABLED|PR_FL_STOPPED))
continue;
if (!(curproxy->cap & PR_CAP_FE))
@ -2416,7 +2416,7 @@ void proxy_adjust_all_maxconn()
* loop above because cross-references are not yet fully resolved.
*/
for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
if (curproxy->disabled)
if (curproxy->flags & (PR_FL_DISABLED|PR_FL_STOPPED))
continue;
/* If <fullconn> is not set, let's set it to 10% of the sum of
@ -2875,7 +2875,7 @@ static int cli_parse_shutdown_frontend(char **args, char *payload, struct appctx
if (!px)
return 1;
if (px->disabled)
if (px->flags & (PR_FL_DISABLED|PR_FL_STOPPED))
return cli_msg(appctx, LOG_NOTICE, "Frontend was already shut down.\n");
stop_proxy(px);
@ -2898,7 +2898,7 @@ static int cli_parse_disable_frontend(char **args, char *payload, struct appctx
if (!px)
return 1;
if (px->disabled)
if (px->flags & (PR_FL_DISABLED|PR_FL_STOPPED))
return cli_msg(appctx, LOG_NOTICE, "Frontend was previously shut down, cannot disable.\n");
if (!px->li_ready)
@ -2930,7 +2930,7 @@ static int cli_parse_enable_frontend(char **args, char *payload, struct appctx *
if (!px)
return 1;
if (px->disabled)
if (px->flags & (PR_FL_DISABLED|PR_FL_STOPPED))
return cli_err(appctx, "Frontend was previously shut down, cannot enable.\n");
if (px->li_ready == px->li_all)

View File

@ -3865,7 +3865,7 @@ int srv_init_addr(void)
struct server *srv;
/* servers are in backend only */
if (!(curproxy->cap & PR_CAP_BE) || curproxy->disabled)
if (!(curproxy->cap & PR_CAP_BE) || (curproxy->flags & (PR_FL_DISABLED|PR_FL_STOPPED)))
goto srv_init_addr_next;
for (srv = curproxy->srv; srv; srv = srv->next) {
@ -3954,7 +3954,7 @@ struct server *cli_find_server(struct appctx *appctx, char *arg)
return NULL;
}
if (px->disabled) {
if (px->flags & (PR_FL_DISABLED|PR_FL_STOPPED)) {
cli_err(appctx, "Proxy is disabled.\n");
return NULL;
}

View File

@ -830,7 +830,7 @@ void apply_server_state(void)
struct eb_root local_state_tree = EB_ROOT_UNIQUE;
/* Must be an enabled backend with at least a server */
if (!(curproxy->cap & PR_CAP_BE) || curproxy->disabled || !curproxy->srv)
if (!(curproxy->cap & PR_CAP_BE) || (curproxy->flags & (PR_FL_DISABLED|PR_FL_STOPPED)) || !curproxy->srv)
continue; /* next proxy */
/* Mode must be specified */

View File

@ -1695,7 +1695,7 @@ int stats_fill_fe_stats(struct proxy *px, struct field *stats, int len,
metric = mkf_u64(FN_COUNTER, px->fe_counters.denied_sess);
break;
case ST_F_STATUS:
metric = mkf_str(FO_STATUS, px->disabled ? "STOP" : "OPEN");
metric = mkf_str(FO_STATUS, (px->flags & (PR_FL_DISABLED|PR_FL_STOPPED)) ? "STOP" : "OPEN");
break;
case ST_F_PID:
metric = mkf_u32(FO_KEY, 1);
@ -3678,7 +3678,7 @@ static int stats_dump_proxies(struct stream_interface *si,
* Also skip proxies that were disabled in the configuration
* This change allows retrieving stats from "old" proxies after a reload.
*/
if (!(px->disabled & PR_DISABLED) && px->uuid > 0 &&
if (!(px->flags & PR_FL_DISABLED) && px->uuid > 0 &&
(px->cap & (PR_CAP_FE | PR_CAP_BE)) && !(px->cap & PR_CAP_INT)) {
if (stats_dump_proxy_to_buffer(si, htx, px, uri) == 0)
return 0;
@ -4091,7 +4091,7 @@ static int stats_process_http_post(struct stream_interface *si)
total_servers++;
break;
case ST_ADM_ACTION_SHUTDOWN:
if (!px->disabled) {
if (!(px->flags & (PR_FL_DISABLED|PR_FL_STOPPED))) {
srv_shutdown_streams(sv, SF_ERR_KILLED);
altered_servers++;
total_servers++;

View File

@ -654,7 +654,7 @@ int stktable_init(struct stktable *t)
t->exp_task->process = process_table_expire;
t->exp_task->context = (void *)t;
}
if (t->peers.p && t->peers.p->peers_fe && !t->peers.p->peers_fe->disabled) {
if (t->peers.p && t->peers.p->peers_fe && !(t->peers.p->peers_fe->flags & (PR_FL_DISABLED|PR_FL_STOPPED))) {
peers_retval = peers_register_table(t->peers.p, t);
}

View File

@ -747,7 +747,7 @@ static void stream_free(struct stream *s)
pool_free(pool_head_stream, s);
/* We may want to free the maximum amount of pools if the proxy is stopping */
if (fe && unlikely(fe->disabled)) {
if (fe && unlikely(fe->flags & (PR_FL_DISABLED|PR_FL_STOPPED))) {
pool_flush(pool_head_buffer);
pool_flush(pool_head_http_txn);
pool_flush(pool_head_requri);