From 9580d16e4018e9d2db1a9fcad21ba17c367f0436 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Sat, 19 May 2012 19:07:40 +0200 Subject: [PATCH] BUG/MAJOR: checks: don't call set_server_status_* when no LB algo is set David Touzeau reported that haproxy dies when a server is checked and is used in a farm with only "option transparent" and no LB algo. This is because the LB params are NULL, the functions should be checked before being called. The same bug is present in 1.4 so this patch must be backported. --- include/types/backend.h | 2 +- src/checks.c | 12 ++++++++---- src/dumpstats.c | 12 ++++++++---- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/include/types/backend.h b/include/types/backend.h index 8672bd2465..fd66e407a6 100644 --- a/include/types/backend.h +++ b/include/types/backend.h @@ -134,7 +134,7 @@ struct lbprm { struct lb_fwlc fwlc; struct lb_chash chash; struct lb_fas fas; - /* Call backs for some actions. Some may be NULL (thus should be ignored). */ + /* Call backs for some actions. Any of them may be NULL (thus should be ignored). */ void (*update_server_eweight)(struct server *); /* to be called after eweight change */ void (*set_server_status_up)(struct server *); /* to be called after status changes to UP */ void (*set_server_status_down)(struct server *); /* to be called after status changes to DOWN */ diff --git a/src/checks.c b/src/checks.c index 78ec4ad6dd..febf77e7b7 100644 --- a/src/checks.c +++ b/src/checks.c @@ -390,7 +390,8 @@ void set_server_down(struct server *s) s->last_change = now.tv_sec; s->state &= ~(SRV_RUNNING | SRV_GOINGDOWN); - s->proxy->lbprm.set_server_status_down(s); + if (s->proxy->lbprm.set_server_status_down) + s->proxy->lbprm.set_server_status_down(s); if (s->onmarkeddown & HANA_ONMARKEDDOWN_SHUTDOWNSESSIONS) shutdown_sessions(s); @@ -476,7 +477,8 @@ void set_server_up(struct server *s) { } task_schedule(s->warmup, tick_add(now_ms, MS_TO_TICKS(MAX(1000, s->slowstart / 20)))); } - s->proxy->lbprm.set_server_status_up(s); + if (s->proxy->lbprm.set_server_status_up) + s->proxy->lbprm.set_server_status_up(s); /* check if we can handle some connections queued at the proxy. We * will take as many as we can handle. @@ -521,7 +523,8 @@ static void set_server_disabled(struct server *s) { int xferred; s->state |= SRV_GOINGDOWN; - s->proxy->lbprm.set_server_status_down(s); + if (s->proxy->lbprm.set_server_status_down) + s->proxy->lbprm.set_server_status_down(s); /* we might have sessions queued on this server and waiting for * a connection. Those which are redispatchable will be queued @@ -558,7 +561,8 @@ static void set_server_enabled(struct server *s) { int xferred; s->state &= ~SRV_GOINGDOWN; - s->proxy->lbprm.set_server_status_up(s); + if (s->proxy->lbprm.set_server_status_up) + s->proxy->lbprm.set_server_status_up(s); /* check if we can handle some connections queued at the proxy. We * will take as many as we can handle. diff --git a/src/dumpstats.c b/src/dumpstats.c index b95418e94b..4b051d7bf0 100644 --- a/src/dumpstats.c +++ b/src/dumpstats.c @@ -989,10 +989,14 @@ static int stats_sock_parse_request(struct stream_interface *si, char *line) /* static LB algorithms are a bit harder to update */ if (px->lbprm.update_server_eweight) px->lbprm.update_server_eweight(sv); - else if (sv->eweight) - px->lbprm.set_server_status_up(sv); - else - px->lbprm.set_server_status_down(sv); + else if (sv->eweight) { + if (px->lbprm.set_server_status_up) + px->lbprm.set_server_status_up(sv); + } + else { + if (px->lbprm.set_server_status_down) + px->lbprm.set_server_status_down(sv); + } return 1; }