* HAPROXY_MWORKER
* HAPROXY_CLI
* HAPROXY_MASTER_CLI
+ * HAPROXY_MASTER_ID
* HAPROXY_LOCALPEER
Their values are undefined during configuration parsing, they are set later
| HAPROXY_MWORKER | | | | | X | X |
| HAPROXY_CLI | | | | | | X |
| HAPROXY_MASTER_CLI | | | | | X | |
+ | HAPROXY_MASTER_ID | | X | | | X | X |
| HAPROXY_LOCALPEER | | X | | | | X |
| HAPROXY_HTTP_LOG_FMT | | X | | X | | |
| HAPROXY_HTTP_CLF_LOG_FMT | | X | | X | | |
* HAPROXY_MASTER_CLI: In master-worker mode, listeners addresses of the master
CLI, separated by semicolons.
+ * HAPROXY_MASTER_ID: In master-worker mode, unique identifier of the master
+ process. A time-ordered UUID (version 7) is generated when the master
+ starts, unless a valid identifier is already present in the environment; an
+ invalid one is simply replaced by a generated one. It is then passed to the
+ next master upon reload, so that it remains stable for the whole life of
+ the master, and it is also exposed to the worker. Its format is the same as
+ the one of the proxies' and servers' "guid": at most 127 characters among
+ letters, digits, '.', ':', '-' and '_'.
+
* HAPROXY_STARTUP_VERSION: contains the version used to start, in master-
worker mode this is the version which was used to start the master, even
after updating the binary and reloading.
char *chroot;
char *pidfile;
char *node, *desc; /* node name & description */
+ char *master_id; /* master process' unique ID, preserved upon reload */
int localpeer_cmdline; /* whether or not the commandline "-L" was set */
int fd_hard_limit; /* hard limit on ulimit-n : 0=unset */
struct buffer log_tag; /* name for syslog */
ha_free(&global.pidfile);
ha_free(&global.node);
ha_free(&global.desc);
+ ha_free(&global.master_id);
ha_free(&oldpids);
ha_free(&old_argv);
ha_free(&localpeer);
exit(EXIT_FAILURE);
}
setenv("HAPROXY_MWORKER", "1", 1);
+
+ /* restore_env() above has dropped it, put it back so
+ * that the worker's config may reference it.
+ */
+ if (global.master_id)
+ setenv("HAPROXY_MASTER_ID", global.master_id, 1);
}
/* localpeer default value could be redefined via 'localpeer' keyword
#include <unistd.h>
#include <haproxy/api.h>
+#include <haproxy/buf.h>
#include <haproxy/cfgparse.h>
#include <haproxy/cli.h>
#include <haproxy/errors.h>
#include <haproxy/fd.h>
#include <haproxy/global.h>
+#include <haproxy/guid.h>
#include <haproxy/log.h>
#include <haproxy/list.h>
#include <haproxy/listener.h>
setenv("HAPROXY_MWORKER_REEXEC", "1", 1);
+ /* restore_env() above has dropped it, but the next master must keep
+ * the ID of the current one, which is the whole point of passing it
+ * through the environment.
+ */
+ if (global.master_id)
+ setenv("HAPROXY_MASTER_ID", global.master_id, 1);
+
mworker_proc_list_to_env(); /* put the children description in the env */
/* during the reload we must ensure that every FDs that can't be
void mworker_prepare_master(void)
{
struct mworker_proc *tmproc;
+ char uuid[40];
+ const char *id;
setenv("HAPROXY_MWORKER", "1", 1);
+ /* Assign a unique ID to this master process. It is taken from the
+ * environment when a valid one is found there, which happens either on
+ * reload since the previous master passes its own to us, or when an
+ * orchestrator wants to force it. Otherwise a time-ordered UUID v7 is
+ * generated. This way it identifies this master for its whole life.
+ */
+ id = getenv("HAPROXY_MASTER_ID");
+ if (!id || !guid_is_valid_fmt(id, NULL)) {
+ struct buffer buf = b_make(uuid, sizeof(uuid), 0, 0);
+
+ ha_generate_uuid_v7(&buf);
+ id = uuid;
+ }
+
+ global.master_id = strdup(id);
+ if (!global.master_id) {
+ ha_alert("Cannot allocate memory for the master's ID.\n");
+ exit(EXIT_FAILURE);
+ }
+ setenv("HAPROXY_MASTER_ID", global.master_id, 1);
+
if (getenv("HAPROXY_MWORKER_REEXEC") == NULL) {
tmproc = mworker_proc_new();