BUG/MINOR: server: Fix server-state-file-name directive

Since the beginning, this directive is documented to accept an optional file
name. But it should also be possible to use it without any argument to use
the backend name as file name. However, when no argument is provided, an
error is reported during the configuration parsing requesting an argument, a
file name or "use-backend-name". And This last special argument is not
documented.

So, to respect the documentation and to avoid configuration breakages, all
modes are now supported. If this directive is called with no argument or
with "use-backend-name", the backend name is use as file name for the
server-state file. Otherwise, the provided string is used.

In addition, we take care to release any previously allocated file name in
case this directive is defines multiple times in the same backend. And an
error is reported if more than one argument are defined. Finally, the
documentation is updated accordingly. Sections supporting this directive are
also mentioned.

This patch should be backported as far as 1.6.
This commit is contained in:
Christopher Faulet 2021-02-12 09:27:10 +01:00
parent ddc7ce9645
commit 583b6de68a
2 changed files with 17 additions and 13 deletions

View File

@ -9720,13 +9720,17 @@ server <name> <address>[:[port]] [param*]
See also: "default-server", "http-send-name-header" and section 5 about See also: "default-server", "http-send-name-header" and section 5 about
server options server options
server-state-file-name [<file>] server-state-file-name [ { use-backend-name | <file> } ]
Set the server state file to read, load and apply to servers available in Set the server state file to read, load and apply to servers available in
this backend. It only applies when the directive "load-server-state-from-file" this backend.
is set to "local". When <file> is not provided or if this directive is not May be used in sections: defaults | frontend | listen | backend
set, then backend name is used. If <file> starts with a slash '/', then it is no | no | yes | yes
considered as an absolute path. Otherwise, <file> is concatenated to the
global directive "server-state-file-base". It only applies when the directive "load-server-state-from-file" is set to
"local". When <file> is not provided, if "use-backend-name" is used or if
this directive is not set, then backend name is used. If <file> starts with a
slash '/', then it is considered as an absolute path. Otherwise, <file> is
concatenated to the global directive "server-state-base".
Example: the minimal configuration below would make HAProxy look for the Example: the minimal configuration below would make HAProxy look for the
state server file '/etc/haproxy/states/bk': state server file '/etc/haproxy/states/bk':
@ -9737,7 +9741,7 @@ server-state-file-name [<file>]
backend bk backend bk
load-server-state-from-file load-server-state-from-file
See also: "server-state-file-base", "load-server-state-from-file", and See also: "server-state-base", "load-server-state-from-file", and
"show servers state" "show servers state"
server-template <prefix> <num | range> <fqdn>[:<port>] [params*] server-template <prefix> <num | range> <fqdn>[:<port>] [params*]

View File

@ -1204,13 +1204,13 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
else if (strcmp(args[0], "server-state-file-name") == 0) { else if (strcmp(args[0], "server-state-file-name") == 0) {
if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL)) if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
err_code |= ERR_WARN; err_code |= ERR_WARN;
if (*(args[1]) == 0) { if (alertif_too_many_args(1, file, linenum, args, &err_code))
ha_alert("parsing [%s:%d] : '%s' expects 'use-backend-name' or a string. Got no argument\n",
file, linenum, args[0]);
err_code |= ERR_ALERT | ERR_FATAL;
goto out; goto out;
}
else if (strcmp(args[1], "use-backend-name") == 0) free(curproxy->server_state_file_name);
curproxy->server_state_file_name = NULL;
if (*(args[1]) == 0 || strcmp(args[1], "use-backend-name") == 0)
curproxy->server_state_file_name = strdup(curproxy->id); curproxy->server_state_file_name = strdup(curproxy->id);
else else
curproxy->server_state_file_name = strdup(args[1]); curproxy->server_state_file_name = strdup(args[1]);