From 7b01a8dbdd049a3d0778f02bf0876ecc5fc48c16 Mon Sep 17 00:00:00 2001 From: Amaury Denoyelle Date: Mon, 29 Mar 2021 10:29:07 +0200 Subject: [PATCH] MINOR: global: define diagnostic mode of execution Define MODE_DIAG which is used to run haproxy in diagnostic mode. This mode is used to output extra warnings about possible configuration blunder or sub-optimal usage. It can be activated with argument '-dD'. A new output function ha_diag_warning is implemented reserved for diagnostic output. It serves to standardize the format of diagnostic messages. A macro HA_DIAG_WARN_COND is also available to automatically check if diagnostic mode is on before executing the diagnostic check. --- doc/management.txt | 4 ++++ include/haproxy/errors.h | 16 ++++++++++++++++ include/haproxy/global-t.h | 1 + src/haproxy.c | 6 +++++- src/log.c | 36 ++++++++++++++++++++++++++++++++++++ 5 files changed, 62 insertions(+), 1 deletion(-) diff --git a/doc/management.txt b/doc/management.txt index c7eb7fff4e..44183282ac 100644 --- a/doc/management.txt +++ b/doc/management.txt @@ -199,6 +199,10 @@ list of options is : in foreground and to show incoming and outgoing events. It must never be used in an init script. + -dD : enable diagnostic mode. This mode will output extra warnings about + suspicious configuration statements. This will never prevent startup even in + "zero-warning" mode nor change the exit status code. + -dG : disable use of getaddrinfo() to resolve host names into addresses. It can be used when suspecting that getaddrinfo() doesn't work as expected. This option was made available because many bogus implementations of diff --git a/include/haproxy/errors.h b/include/haproxy/errors.h index 521876f74e..e0eff9c3cc 100644 --- a/include/haproxy/errors.h +++ b/include/haproxy/errors.h @@ -74,6 +74,22 @@ void ha_alert(const char *fmt, ...) void ha_warning(const char *fmt, ...) __attribute__ ((format(printf, 1, 2))); +/* + * These functions are reserved to output diagnostics on MODE_DIAG. + * Use the underscore variants only if MODE_DIAG has already been checked. + */ +void _ha_vdiag_warning(const char *fmt, va_list argp); +void _ha_diag_warning(const char *fmt, ...); +void ha_diag_warning(const char *fmt, ...) + __attribute__ ((format(printf, 1 ,2))); + +/* Check for both MODE_DIAG and before outputting a diagnostic warning */ +#define HA_DIAG_WARNING_COND(cond, fmt, ...) \ + do { \ + if ((global.mode & MODE_DIAG) && (cond)) \ + _ha_diag_warning((fmt), __VA_ARGS__); \ + } while (0) + /* * Displays the message on stderr with the date and pid. */ diff --git a/include/haproxy/global-t.h b/include/haproxy/global-t.h index 3bbdd72907..c98a0fabae 100644 --- a/include/haproxy/global-t.h +++ b/include/haproxy/global-t.h @@ -38,6 +38,7 @@ #define MODE_MWORKER 0x80 /* Master Worker */ #define MODE_MWORKER_WAIT 0x100 /* Master Worker wait mode */ #define MODE_ZERO_WARNING 0x200 /* warnings cause a failure */ +#define MODE_DIAG 0x400 /* extra warnings */ /* list of last checks to perform, depending on config options */ #define LSTCHK_CAP_BIND 0x00000001 /* check that we can bind to any port */ diff --git a/src/haproxy.c b/src/haproxy.c index 50d91f770a..aeb92e6b07 100644 --- a/src/haproxy.c +++ b/src/haproxy.c @@ -403,6 +403,7 @@ static void usage(char *name) " -dr ignores server address resolution failures\n" " -dV disables SSL verify on servers side\n" " -dW fails if any warning is emitted\n" + " -dD diagnostic mode : warn about suspicious configuration statements\n" " -sf/-st [pid ]* finishes/terminates old pids.\n" " -x get listening sockets from a unix socket\n" " -S [,...] new master CLI\n" @@ -1401,6 +1402,8 @@ static void init(int argc, char **argv) arg_mode |= MODE_VERBOSE; else if (*flag == 'd' && flag[1] == 'b') arg_mode |= MODE_FOREGROUND; + else if (*flag == 'd' && flag[1] == 'D') + arg_mode |= MODE_DIAG; else if (*flag == 'd' && flag[1] == 'W') arg_mode |= MODE_ZERO_WARNING; else if (*flag == 'd' && flag[1] == 'M') @@ -1541,7 +1544,8 @@ static void init(int argc, char **argv) } global.mode |= (arg_mode & (MODE_DAEMON | MODE_MWORKER | MODE_FOREGROUND | MODE_VERBOSE - | MODE_QUIET | MODE_CHECK | MODE_DEBUG | MODE_ZERO_WARNING)); + | MODE_QUIET | MODE_CHECK | MODE_DEBUG | MODE_ZERO_WARNING + | MODE_DIAG)); if (getenv("HAPROXY_MWORKER_WAIT_ONLY")) { unsetenv("HAPROXY_MWORKER_WAIT_ONLY"); diff --git a/src/log.c b/src/log.c index e002c48ac2..292eb588a8 100644 --- a/src/log.c +++ b/src/log.c @@ -1133,6 +1133,42 @@ void ha_warning(const char *fmt, ...) } } +/* + * Variant of _ha_diag_warning with va_list. + * Use it only if MODE_DIAG has been previously checked. + */ +void _ha_vdiag_warning(const char *fmt, va_list argp) +{ + print_message("DIAG/WARNING", fmt, argp); +} + +/* + * Output a diagnostic warning. + * Use it only if MODE_DIAG has been previously checked. + */ +void _ha_diag_warning(const char *fmt, ...) +{ + va_list argp; + + va_start(argp, fmt); + _ha_vdiag_warning(fmt, argp); + va_end(argp); +} + +/* + * Output a diagnostic warning. Do nothing of MODE_DIAG is not on. + */ +void ha_diag_warning(const char *fmt, ...) +{ + va_list argp; + + if (global.mode & MODE_DIAG) { + va_start(argp, fmt); + _ha_vdiag_warning(fmt, argp); + va_end(argp); + } +} + /* * Displays the message on stderr with the date and pid. */ -- 2.39.5