From a0e8eb8caaf1632500bab0dfe0c017540d0d71cb Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Fri, 12 Mar 2021 09:30:14 +0100 Subject: [PATCH] MINOR: cfgparse: suggest correct spelling for unknown words in global section The global section also knows a large number of keywords that are not referenced in any list, so this needed them to be specifically listed. It becomes particularly handy now because some tunables are never easy to remember, but now it works remarkably well: $ printf "global\nsched.queue_depth\n" | ./haproxy -c -f /dev/stdin [NOTICE] 070/093007 (23457) : haproxy version is 2.4-dev11-dd8ee5-24 [NOTICE] 070/093007 (23457) : path to executable is ./haproxy [ALERT] 070/093007 (23457) : parsing [/dev/stdin:2] : unknown keyword 'sched.queue_depth' in 'global' section; did you mean 'tune.runqueue-depth' maybe ? [ALERT] 070/093007 (23457) : Error(s) found in configuration file : /dev/stdin [ALERT] 070/093007 (23457) : Fatal errors found in configuration. --- src/cfgparse-global.c | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/src/cfgparse-global.c b/src/cfgparse-global.c index ddb5e4cf16..fc56fbf417 100644 --- a/src/cfgparse-global.c +++ b/src/cfgparse-global.c @@ -19,6 +19,32 @@ #include #include +/* some keywords that are still being parsed using strcmp() and are not + * registered anywhere. They are used as suggestions for mistyped words. + */ +static const char *common_kw_list[] = { + "global", "daemon", "master-worker", "noepoll", "nokqueue", + "noevports", "nopoll", "busy-polling", "set-dumpable", + "insecure-fork-wanted", "insecure-setuid-wanted", "nosplice", + "nogetaddrinfo", "noreuseport", "quiet", "zero-warning", + "tune.runqueue-depth", "tune.maxpollevents", "tune.maxaccept", + "tune.chksize", "tune.recv_enough", "tune.buffers.limit", + "tune.buffers.reserve", "tune.bufsize", "tune.maxrewrite", + "tune.idletimer", "tune.rcvbuf.client", "tune.rcvbuf.server", + "tune.sndbuf.client", "tune.sndbuf.server", "tune.pipesize", + "tune.http.cookielen", "tune.http.logurilen", "tune.http.maxhdr", + "tune.comp.maxlevel", "tune.pattern.cache-size", "uid", "gid", + "external-check", "user", "group", "nbproc", "nbthread", "maxconn", + "ssl-server-verify", "maxconnrate", "maxsessrate", "maxsslrate", + "maxcomprate", "maxpipes", "maxzlibmem", "maxcompcpuusage", "ulimit-n", + "chroot", "description", "node", "pidfile", "unix-bind", "log", + "log-send-hostname", "server-state-base", "server-state-file", + "log-tag", "spread-checks", "max-spread-checks", "cpu-map", "setenv", + "presetenv", "unsetenv", "resetenv", "strict-limits", "localpeer", + "defaults", "listen", "frontend", "backend", "peers", "resolvers", + NULL /* must be last */ +}; + /* * parse a line in a section. Returns the error code, 0 if OK, or * any combination of : @@ -1235,6 +1261,7 @@ int cfg_parse_global(const char *file, int linenum, char **args, int kwm) } else { struct cfg_kw_list *kwl; + const char *best; int index; int rc; @@ -1258,7 +1285,11 @@ int cfg_parse_global(const char *file, int linenum, char **args, int kwm) } } - ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], "global"); + best = cfg_find_best_match(args[0], &cfg_keywords.list, CFG_LISTEN, common_kw_list); + if (best) + ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section; did you mean '%s' maybe ?\n", file, linenum, args[0], cursection, best); + else + ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], "global"); err_code |= ERR_ALERT | ERR_FATAL; } -- 2.39.5