]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: startup: fix error path for master, if can't open pidfile
authorValentine Krasnobaeva <vkrasnobaeva@haproxy.com>
Tue, 3 Dec 2024 20:33:55 +0000 (21:33 +0100)
committerWilliam Lallemand <wlallemand@haproxy.com>
Fri, 6 Dec 2024 11:00:22 +0000 (12:00 +0100)
If master process can't open a pidfile, there is no sense to send SIGTTIN to
oldpids, as it will exit. So, old workers will terminate as well. It's better
to send the last alert to the log about unrecoverable error, because master is
already in its polling loop.

For the standalone mode we should keep the previous logic in this case: send
SIGTTIN to old process and unbind listeners for the new one. So, it's better
to put this error path in main(), as it's done when other configuration settings
can't be applied.

This patch should be backported only in 3.1.

include/haproxy/global.h
src/cli.c
src/haproxy.c

index 13fbe7c7cd70cb258bfebdf679931bf93d9d36a0..3c09968c5b68f5b86dc915f5824c54bbc3091766 100644 (file)
@@ -68,7 +68,7 @@ void hap_register_feature(const char *name);
 int split_version(const char *version, unsigned int *value);
 int compare_current_version(const char *version);
 void display_version();
-void handle_pidfile(void);
+int handle_pidfile(void);
 
 void mworker_accept_wrapper(int fd);
 
index e5d8fc562101d9ed5c8fc36cc09a6cb36dd0c006..1befd8ee0cced92e388f920f36530b2d7f56d601 100644 (file)
--- a/src/cli.c
+++ b/src/cli.c
@@ -2523,8 +2523,12 @@ static int _send_status(char **args, char *payload, struct appctx *appctx, void
         * so we can write our PID in a pidfile, if provided. Master doesn't
         * perform chroot.
         */
-       if (global.pidfile != NULL)
-               handle_pidfile();
+       if (global.pidfile != NULL) {
+               if (handle_pidfile() < 0) {
+                       ha_alert("Fatal error(s) found, exiting.\n");
+                       exit(1);
+               }
+       }
 
        /* either send USR1/TERM to old master, case when we launched as -W -D ... -sf $(cat pidfile),
         * or send USR1/TERM to old worker processes.
index eac6329a1ec41332ceadecbd99d07e51c62c7bcb..120822ba6fb9ec514842c0189d5a3fa9504fcab8 100644 (file)
@@ -1776,8 +1776,8 @@ static void apply_daemon_mode()
        }
 }
 
-/* Only returns if everything is OK. If something fails, it exits. */
-void handle_pidfile(void)
+/* Returns 0, if everything is OK. If open() fails, returns -1. */
+int handle_pidfile(void)
 {
        char pidstr[100];
 
@@ -1785,16 +1785,15 @@ void handle_pidfile(void)
        pidfd = open(global.pidfile, O_CREAT | O_WRONLY | O_TRUNC, 0644);
        if (pidfd < 0) {
                ha_alert("[%s.main()] Cannot create pidfile %s\n", progname, global.pidfile);
-               if (nb_oldpids)
-                       tell_old_pids(SIGTTIN);
-               protocol_unbind_all();
-               exit(1);
+               return -1;
        }
        snprintf(pidstr, sizeof(pidstr), "%d\n", (int)getpid());
        DISGUISE(write(pidfd, pidstr, strlen(pidstr)));
        close(pidfd);
        /* We won't ever use this anymore */
        ha_free(&global.pidfile);
+
+       return 0;
 }
 
 static void get_listeners_fd()
@@ -3529,7 +3528,13 @@ int main(int argc, char **argv)
         */
        if (!(global.mode & MODE_MWORKER)) {
                if (global.mode & MODE_DAEMON && (global.pidfile != NULL)) {
-                       handle_pidfile();
+                       if (handle_pidfile() < 0) {
+                               if (nb_oldpids) {
+                                       tell_old_pids(SIGTTIN);
+                                       protocol_unbind_all();
+                               }
+                               exit(1);
+                       }
                }
        }