]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: startup: reintroduce *env keywords support
authorValentine Krasnobaeva <vkrasnobaeva@haproxy.com>
Sat, 12 Oct 2024 12:44:03 +0000 (14:44 +0200)
committerWilly Tarreau <w@1wt.eu>
Wed, 16 Oct 2024 20:02:39 +0000 (22:02 +0200)
setenv/resetenv/presetenv/unsetenv keywords in the configuration modify the
process environment. In case of master-worker and programs we need to restore
the initial process environment before reload, as the configuration could
change in between and newly forked workers and programs should be launched
in the environment corresponded to this new configuration.

To achieve this we backup the initial process environment before the first
configuration read, when 'global' and 'program' sections are read. And then we
clean up master process environment and restore the initial one from the backup
in mworker_reexec().

src/haproxy.c

index 4e25aedea9db85faede5ba930cf1d08007ce90ab..920788b22cf2d5e6535ca866f2ded5ffd4690028 100644 (file)
@@ -155,7 +155,7 @@ char *build_features = "";
 /* list of config files */
 static struct list cfg_cfgfiles = LIST_HEAD_INIT(cfg_cfgfiles);
 int  pid;                      /* current process id */
-char **init_env;
+char **init_env;               /* to keep current process env variables backup */
 int  pidfd = -1;               /* FD to keep PID */
 
 static unsigned long stopping_tgroup_mask; /* Thread groups acknowledging stopping */
@@ -727,6 +727,24 @@ static void mworker_reexec(int hardreload)
        int x_off = 0; /* disable -x by putting -x /dev/null */
 
        mworker_block_signals();
+
+       /* restore initial environment (before parsing the config) and do re-exec.
+        * The initial process environment should be restored here, preceded by
+        * clean_env(), which do the same job as clearenv().
+        * Otherwise, after the re-exec we will start the new worker in the
+        * environment modified by '*env' keywords from the previous configuration,
+        * i.e. existed before the reload.
+        */
+       if (clean_env() != 0) {
+               ha_alert("Master encountered a non-recoverable error, exiting.\n");
+               exit(EXIT_FAILURE);
+       }
+
+       if (restore_env() != 0) {
+               ha_alert("Master encountered a non-recoverable error, exiting.\n");
+               exit(EXIT_FAILURE);
+       }
+
        setenv("HAPROXY_MWORKER_REEXEC", "1", 1);
 
        mworker_cleanup_proc();
@@ -3729,6 +3747,12 @@ int main(int argc, char **argv)
                }
        }
 
+       /* backup initial process env, because parse_cfg() could modify it with
+        * setenv/unsetenv/presetenv/resetenv keywords.
+        */
+       if (backup_env() != 0)
+               exit(EXIT_FAILURE);
+
        /* parse conf in disovery mode and set modes from config */
        read_cfg_in_discovery_mode(argc, argv);
 
@@ -3775,6 +3799,18 @@ int main(int argc, char **argv)
                 * reset non_global_section_parsed counter for the second
                 * configuration reading
                 */
+               if (global.mode & MODE_MWORKER) {
+                       if (clean_env() != 0) {
+                               ha_alert("Worker failed to clean its env, exiting.\n");
+                               exit(EXIT_FAILURE);
+                       }
+
+                       if (restore_env() != 0) {
+                               ha_alert("Worker failed to restore its env, exiting.\n");
+                               exit(EXIT_FAILURE);
+                       }
+                       setenv("HAPROXY_MWORKER", "1", 1);
+               }
                non_global_section_parsed = 0;
                if (read_cfg(progname) < 0) {
                        list_for_each_entry_safe(cfg, cfg_tmp, &cfg_cfgfiles, list) {