From 295071007b1bf83eb0d66ad88b05d6aef05c69eb Mon Sep 17 00:00:00 2001 From: Valentine Krasnobaeva Date: Mon, 2 Dec 2024 16:05:16 +0100 Subject: [PATCH] BUG/MINOR: startup: fix pidfile creation Pidfile should be created at the latest initialization stage, when we are sure, that process is able to start successfully, otherwise PID value, written in this file is no longer valid. So, for the standalone mode, let's move the block, which opens the pidfile and let's put it just before applying "chroot". In master-worker mode, master doesn't perform chroot. So it creates the pidfile, only when the "READY" message from the newly forked worker is received. This should be backported only in 3.1 --- src/cli.c | 8 ++++++++ src/haproxy.c | 13 +++++++++---- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/cli.c b/src/cli.c index a64ce8aa2f3e..05baf85ee6ba 100644 --- a/src/cli.c +++ b/src/cli.c @@ -2526,6 +2526,14 @@ static int _send_status(char **args, char *payload, struct appctx *appctx, void kill(proc->pid, oldpids_sig); } } + + /* At this point we are sure, that newly forked worker is started, + * so we can write our PID in a pidfile, if provided. Master doesn't + * perform chroot. + */ + if (global.pidfile != NULL) + handle_pidfile(); + load_status = 1; ha_notice("Loading success.\n"); diff --git a/src/haproxy.c b/src/haproxy.c index fd77f35454f0..1efa4a8b3c7b 100644 --- a/src/haproxy.c +++ b/src/haproxy.c @@ -3370,10 +3370,6 @@ int main(int argc, char **argv) if ((getenv("HAPROXY_MWORKER_REEXEC") == NULL) && (global.mode & MODE_DAEMON)) apply_daemon_mode(); - /* Open pid file before the chroot */ - if ((global.mode & MODE_DAEMON || global.mode & MODE_MWORKER) && global.pidfile != NULL) - handle_pidfile(); - /* Master-worker and program forks */ if (global.mode & MODE_MWORKER) { /* fork and run binary from command keyword in program section */ @@ -3528,6 +3524,15 @@ int main(int argc, char **argv) } } + /* Open PID file before the chroot. In master-worker mode, it's master + * who will create the pidfile, see _send_status(). + */ + if (!(global.mode & MODE_MWORKER)) { + if (global.mode & MODE_DAEMON && (global.pidfile != NULL)) { + handle_pidfile(); + } + } + /* Must chroot and setgid/setuid in the children */ /* chroot if needed */ if (global.chroot != NULL) {