MEDIUM: cli: allow the stats socket to be bound to a specific set of processes
Using "stats bind-process", it becomes possible to indicate to haproxy which
process will get the incoming connections to the stats socket. It will also
shut down the warning when nbproc > 1.
diff --git a/doc/configuration.txt b/doc/configuration.txt
index 4167d5e..69f4591 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -577,6 +577,15 @@
the "-p" command line argument. The file must be accessible to the user
starting the process. See also "daemon".
+stats bind-process [ all | odd | even | <number 1-32> ] ...
+ Limits the stats socket to a certain set of processes numbers. By default the
+ stats socket is bound to all processes, causing a warning to be emitted when
+ nbproc is greater than 1 because there is no way to select the target process
+ when connecting. However, by using this setting, it becomes possible to pin
+ the stats socket to a specific set of processes, typically the first one. The
+ warning will automatically be disabled when this setting is used, whatever
+ the number of processes used.
+
stats socket [<address:port>|<path>] [param*]
Binds a UNIX socket to <path> or a TCPv4/v6 address to <address:port>.
Connections to this socket will return various statistics outputs and even
diff --git a/src/cfgparse.c b/src/cfgparse.c
index 3c77eed..3f43f58 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -6646,8 +6646,8 @@
/* Check multi-process mode compatibility */
if (global.nbproc > 1) {
- if (global.stats_fe) {
- Warning("stats socket will not work correctly in multi-process mode (nbproc > 1).\n");
+ if (global.stats_fe && !global.stats_fe->bind_proc) {
+ Warning("stats socket will not work as expected in multi-process mode (nbproc > 1), you should force process binding using 'stats bind-process'.\n");
}
}
diff --git a/src/dumpstats.c b/src/dumpstats.c
index fd7d422..d0f0345 100644
--- a/src/dumpstats.c
+++ b/src/dumpstats.c
@@ -300,8 +300,38 @@
}
global.stats_fe->maxconn = maxconn;
}
+ else if (!strcmp(args[1], "bind-process")) { /* enable the socket only on some processes */
+ int cur_arg = 2;
+ unsigned int set = 0;
+
+ while (*args[cur_arg]) {
+ int u;
+ if (strcmp(args[cur_arg], "all") == 0) {
+ set = 0;
+ break;
+ }
+ else if (strcmp(args[cur_arg], "odd") == 0) {
+ set |= 0x55555555;
+ }
+ else if (strcmp(args[cur_arg], "even") == 0) {
+ set |= 0xAAAAAAAA;
+ }
+ else {
+ u = str2uic(args[cur_arg]);
+ if (u < 1 || u > 32) {
+ memprintf(err,
+ "'%s %s' expects 'all', 'odd', 'even', or process numbers from 1 to 32.\n",
+ args[0], args[1]);
+ return -1;
+ }
+ set |= 1 << (u - 1);
+ }
+ cur_arg++;
+ }
+ global.stats_fe->bind_proc = set;
+ }
else {
- memprintf(err, "'%s' only supports 'socket', 'maxconn' and 'timeout' (got '%s')", args[0], args[1]);
+ memprintf(err, "'%s' only supports 'socket', 'maxconn', 'bind-process' and 'timeout' (got '%s')", args[0], args[1]);
return -1;
}
return 0;