Hi,
This implements the feature discussed in the earlier thread of killing
connections on backup servers when a non-backup server comes back up. For
example, you can use this to route to a mysql master & slave and ensure
clients don't stay on the slave after the master goes from down->up. I've done
some minimal testing and it seems to work.
Today is the first time I ever looked at haproxy's code but this feature seemed
straightforward enough to implement. I hope I've done it properly.
Justin
diff --git a/include/types/checks.h b/include/types/checks.h
index fd15c95..250a68f 100644
--- a/include/types/checks.h
+++ b/include/types/checks.h
@@ -80,6 +80,12 @@ enum {
};
enum {
+ HANA_ONMARKEDUP_NONE = 0,
+
+ HANA_ONMARKEDUP_SHUTDOWNBACKUPSESSIONS, /* Shutdown peer sessions */
+};
+
+enum {
HANA_OBS_NONE = 0,
HANA_OBS_LAYER4, /* Observe L4 - for example tcp */
diff --git a/include/types/server.h b/include/types/server.h
index aa2c4f8..1885eab 100644
--- a/include/types/server.h
+++ b/include/types/server.h
@@ -120,7 +120,8 @@ struct server {
int rise, fall; /* time in iterations */
int consecutive_errors_limit; /* number of consecutive errors that triggers an event */
short observe, onerror; /* observing mode: one of HANA_OBS_*; what to do on error: on of ANA_ONERR_* */
- short onmarkeddown; /* what to do when marked down: on of HANA_ONMARKEDDOWN_* */
+ short onmarkeddown; /* what to do when marked down: one of HANA_ONMARKEDDOWN_* */
+ short onmarkedup; /* what to do when marked up: one of HANA_ONMARKEDUP_* */
int inter, fastinter, downinter; /* checks: time in milliseconds */
int slowstart; /* slowstart time in seconds (ms in the conf) */
int result; /* health-check result : SRV_CHK_* */
diff --git a/include/types/session.h b/include/types/session.h
index f1b7451..a098002 100644
--- a/include/types/session.h
+++ b/include/types/session.h
@@ -67,6 +67,7 @@
#define SN_ERR_INTERNAL 0x00007000 /* the proxy encountered an internal error */
#define SN_ERR_DOWN 0x00008000 /* the proxy killed a session because the backend became unavailable */
#define SN_ERR_KILLED 0x00009000 /* the proxy killed a session because it was asked to do so */
+#define SN_ERR_UP 0x0000a000 /* the proxy killed a session because a preferred backend became available */
#define SN_ERR_MASK 0x0000f000 /* mask to get only session error flags */
#define SN_ERR_SHIFT 12 /* bit shift */
diff --git a/src/cfgparse.c b/src/cfgparse.c
index 5bd2cfc..92dd094 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -4392,6 +4392,18 @@ stats_error_parsing:
cur_arg += 2;
}
+ else if (!strcmp(args[cur_arg], "on-marked-up")) {
+ if (!strcmp(args[cur_arg + 1], "shutdown-backup-sessions"))
+ newsrv->onmarkedup = HANA_ONMARKEDUP_SHUTDOWNBACKUPSESSIONS;
+ else {
+ Alert("parsing [%s:%d]: '%s' expects 'shutdown-backup-sessions' but got '%s'\n",
+ file, linenum, args[cur_arg], args[cur_arg + 1]);
+ err_code |= ERR_ALERT | ERR_FATAL;
+ goto out;
+ }
+
+ cur_arg += 2;
+ }
else if (!strcmp(args[cur_arg], "error-limit")) {
if (!*args[cur_arg + 1]) {
Alert("parsing [%s:%d]: '%s' expects an integer argument.\n",
diff --git a/src/checks.c b/src/checks.c
index febf77e..5299e98 100644
--- a/src/checks.c
+++ b/src/checks.c
@@ -358,15 +358,26 @@ static int check_for_pending(struct server *s)
return xferred;
}
-/* Shutdown connections when their server goes down.
+/* Shutdown all connections of a server
*/
-static void shutdown_sessions(struct server *srv)
+static void shutdown_sessions(struct server *srv, int why)
{
struct session *session, *session_bck;
list_for_each_entry_safe(session, session_bck, &srv->actconns, by_srv)
if (session->srv_conn == srv)
- session_shutdown(session, SN_ERR_DOWN);
+ session_shutdown(session, why);
+}
+
+/* Shutdown all connections of all backup servers of a proxy
+ */
+static void shutdown_backup_sessions(struct proxy *px, int why)
+{
+ struct server *srv;
+
+ for (srv = px->srv; srv != NULL; srv = srv->next)
+ if (srv->state & SRV_BACKUP)
+ shutdown_sessions(srv, why);
}
/* Sets server <s> down, notifies by all available means, recounts the
@@ -394,7 +405,7 @@ void set_server_down(struct server *s)
s->proxy->lbprm.set_server_status_down(s);
if (s->onmarkeddown & HANA_ONMARKEDDOWN_SHUTDOWNSESSIONS)
- shutdown_sessions(s);
+ shutdown_sessions(s, SN_ERR_DOWN);
/* we might have sessions queued on this server and waiting for
* a connection. Those which are redispatchable will be queued
@@ -465,6 +476,9 @@ void set_server_up(struct server *s) {
s->state |= SRV_RUNNING;
s->state &= ~SRV_MAINTAIN;
+ if (s->onmarkedup & HANA_ONMARKEDUP_SHUTDOWNBACKUPSESSIONS)
+ shutdown_backup_sessions(s->proxy, SN_ERR_UP);
+
if (s->slowstart > 0) {
s->state |= SRV_WARMINGUP;
if (s->proxy->lbprm.algo & BE_LB_PROP_DYN) {