diff options
Diffstat (limited to 'php-7.3.24-fpm.patch')
-rw-r--r-- | php-7.3.24-fpm.patch | 219 |
1 files changed, 219 insertions, 0 deletions
diff --git a/php-7.3.24-fpm.patch b/php-7.3.24-fpm.patch new file mode 100644 index 0000000..1165970 --- /dev/null +++ b/php-7.3.24-fpm.patch @@ -0,0 +1,219 @@ +Fix for https://bugs.php.net/74083 master PHP-fpm is stopped on multiple reloads +backported for 7.4 from + +From ae5154c6c6af7ba7c592f8af006b7cadd0d66d6e Mon Sep 17 00:00:00 2001 +From: Maksim Nikulin <mnikulin@plesk.com> +Date: Wed, 24 Jul 2019 16:50:57 +0700 +Subject: [PATCH] Block signals during fpm master initialization + +From e37bd5dcc2e8f269c6031d86429311c8cf243060 Mon Sep 17 00:00:00 2001 +From: Maksim Nikulin <mnikulin@plesk.com> +Date: Mon, 21 Oct 2019 14:23:29 +0700 +Subject: [PATCH] Do not let PHP-FPM children miss SIGTERM, SIGQUIT + + +diff -up ./sapi/fpm/fpm/fpm_children.c.fpmsig ./sapi/fpm/fpm/fpm_children.c +--- ./sapi/fpm/fpm/fpm_children.c.fpmsig 2020-10-23 10:36:31.423925856 +0200 ++++ ./sapi/fpm/fpm/fpm_children.c 2020-10-23 10:36:38.872900642 +0200 +@@ -404,6 +404,11 @@ int fpm_children_make(struct fpm_worker_ + return 2; + } + ++ zlog(ZLOG_DEBUG, "blocking signals before child birth"); ++ if (0 > fpm_signals_child_block()) { ++ zlog(ZLOG_WARNING, "child may miss signals"); ++ } ++ + pid = fork(); + + switch (pid) { +@@ -415,12 +420,16 @@ int fpm_children_make(struct fpm_worker_ + return 0; + + case -1 : ++ zlog(ZLOG_DEBUG, "unblocking signals"); ++ fpm_signals_unblock(); + zlog(ZLOG_SYSERROR, "fork() failed"); + + fpm_resources_discard(child); + return 2; + + default : ++ zlog(ZLOG_DEBUG, "unblocking signals, child born"); ++ fpm_signals_unblock(); + child->pid = pid; + fpm_clock_get(&child->started); + fpm_parent_resources_use(child); +diff -up ./sapi/fpm/fpm/fpm_main.c.fpmsig ./sapi/fpm/fpm/fpm_main.c +--- ./sapi/fpm/fpm/fpm_main.c.fpmsig 2020-10-13 11:27:02.000000000 +0200 ++++ ./sapi/fpm/fpm/fpm_main.c 2020-10-23 10:36:38.873900639 +0200 +@@ -90,6 +90,7 @@ int __riscosify_control = __RISCOSIFY_ST + #include "fpm.h" + #include "fpm_request.h" + #include "fpm_status.h" ++#include "fpm_signals.h" + #include "fpm_conf.h" + #include "fpm_php.h" + #include "fpm_log.h" +@@ -1584,6 +1585,11 @@ int main(int argc, char *argv[]) + closes it. in apache|apxs mode apache + does that for us! thies@thieso.net + 20000419 */ ++ ++ if (0 > fpm_signals_init_mask() || 0 > fpm_signals_block()) { ++ zlog(ZLOG_WARNING, "Could die in the case of too early reload signal"); ++ } ++ zlog(ZLOG_DEBUG, "Blocked some signals"); + #endif + #endif + +diff -up ./sapi/fpm/fpm/fpm_process_ctl.c.fpmsig ./sapi/fpm/fpm/fpm_process_ctl.c +--- ./sapi/fpm/fpm/fpm_process_ctl.c.fpmsig 2020-10-13 11:27:02.000000000 +0200 ++++ ./sapi/fpm/fpm/fpm_process_ctl.c 2020-10-23 10:36:11.921991864 +0200 +@@ -77,6 +77,10 @@ static void fpm_pctl_exit() /* {{{ */ + + static void fpm_pctl_exec() /* {{{ */ + { ++ zlog(ZLOG_DEBUG, "Blocking some signals before reexec"); ++ if (0 > fpm_signals_block()) { ++ zlog(ZLOG_WARNING, "concurrent reloads may be unstable"); ++ } + + zlog(ZLOG_NOTICE, "reloading: execvp(\"%s\", {\"%s\"" + "%s%s%s" "%s%s%s" "%s%s%s" "%s%s%s" "%s%s%s" +diff -up ./sapi/fpm/fpm/fpm_signals.c.fpmsig ./sapi/fpm/fpm/fpm_signals.c +--- ./sapi/fpm/fpm/fpm_signals.c.fpmsig 2020-10-13 11:27:02.000000000 +0200 ++++ ./sapi/fpm/fpm/fpm_signals.c 2020-10-23 10:36:38.873900639 +0200 +@@ -19,6 +19,8 @@ + #include "zlog.h" + + static int sp[2]; ++static sigset_t block_sigset; ++static sigset_t child_block_sigset; + + const char *fpm_signal_names[NSIG + 1] = { + #ifdef SIGHUP +@@ -165,8 +167,11 @@ static void sig_handler(int signo) /* {{ + int saved_errno; + + if (fpm_globals.parent_pid != getpid()) { +- /* prevent a signal race condition when child process +- have not set up it's own signal handler yet */ ++ /* Avoid using of signal handlers from the master process in a worker ++ before the child sets up its own signal handlers. ++ Normally it is prevented by the sigprocmask() calls ++ around fork(). This execution branch is a last resort trap ++ that has no protection against #76601. */ + return; + } + +@@ -210,6 +215,11 @@ int fpm_signals_init_main() /* {{{ */ + zlog(ZLOG_SYSERROR, "failed to init signals: sigaction()"); + return -1; + } ++ ++ zlog(ZLOG_DEBUG, "Unblocking all signals"); ++ if (0 > fpm_signals_unblock()) { ++ return -1; ++ } + return 0; + } + /* }}} */ +@@ -241,6 +251,10 @@ int fpm_signals_init_child() /* {{{ */ + } + + zend_signal_init(); ++ ++ if (0 > fpm_signals_unblock()) { ++ return -1; ++ } + return 0; + } + /* }}} */ +@@ -250,3 +264,72 @@ int fpm_signals_get_fd() /* {{{ */ + return sp[0]; + } + /* }}} */ ++ ++int fpm_signals_init_mask() /* {{{ */ ++{ ++ /* Subset of signals from fpm_signals_init_main() and fpm_got_signal() ++ blocked to avoid unexpected death during early init ++ or during reload just after execvp() or fork */ ++ int init_signal_array[] = { SIGUSR1, SIGUSR2, SIGCHLD }; ++ size_t size = sizeof(init_signal_array)/sizeof(init_signal_array[0]); ++ size_t i = 0; ++ if (0 > sigemptyset(&block_sigset) || ++ 0 > sigemptyset(&child_block_sigset)) { ++ zlog(ZLOG_SYSERROR, "failed to prepare signal block mask: sigemptyset()"); ++ return -1; ++ } ++ for (i = 0; i < size; ++i) { ++ int sig_i = init_signal_array[i]; ++ if (0 > sigaddset(&block_sigset, sig_i) || ++ 0 > sigaddset(&child_block_sigset, sig_i)) { ++ if (sig_i <= NSIG && fpm_signal_names[sig_i] != NULL) { ++ zlog(ZLOG_SYSERROR, "failed to prepare signal block mask: sigaddset(%s)", ++ fpm_signal_names[sig_i]); ++ } else { ++ zlog(ZLOG_SYSERROR, "failed to prepare signal block mask: sigaddset(%d)", sig_i); ++ } ++ return -1; ++ } ++ } ++ if (0 > sigaddset(&child_block_sigset, SIGTERM) || ++ 0 > sigaddset(&child_block_sigset, SIGQUIT)) { ++ zlog(ZLOG_SYSERROR, "failed to prepare child signal block mask: sigaddset()"); ++ return -1; ++ } ++ return 0; ++} ++/* }}} */ ++ ++int fpm_signals_block() /* {{{ */ ++{ ++ if (0 > sigprocmask(SIG_BLOCK, &block_sigset, NULL)) { ++ zlog(ZLOG_SYSERROR, "failed to block signals"); ++ return -1; ++ } ++ return 0; ++} ++/* }}} */ ++ ++int fpm_signals_child_block() /* {{{ */ ++{ ++ if (0 > sigprocmask(SIG_BLOCK, &child_block_sigset, NULL)) { ++ zlog(ZLOG_SYSERROR, "failed to block child signals"); ++ return -1; ++ } ++ return 0; ++} ++/* }}} */ ++ ++int fpm_signals_unblock() /* {{{ */ ++{ ++ /* Ensure that during reload after upgrade all signals are unblocked. ++ block_sigset could have different value before execve() */ ++ sigset_t all_signals; ++ sigfillset(&all_signals); ++ if (0 > sigprocmask(SIG_UNBLOCK, &all_signals, NULL)) { ++ zlog(ZLOG_SYSERROR, "failed to unblock signals"); ++ return -1; ++ } ++ return 0; ++} ++/* }}} */ +diff -up ./sapi/fpm/fpm/fpm_signals.h.fpmsig ./sapi/fpm/fpm/fpm_signals.h +--- ./sapi/fpm/fpm/fpm_signals.h.fpmsig 2020-10-13 11:27:02.000000000 +0200 ++++ ./sapi/fpm/fpm/fpm_signals.h 2020-10-23 10:36:38.873900639 +0200 +@@ -8,6 +8,10 @@ + int fpm_signals_init_main(); + int fpm_signals_init_child(); + int fpm_signals_get_fd(); ++int fpm_signals_init_mask(); ++int fpm_signals_block(); ++int fpm_signals_child_block(); ++int fpm_signals_unblock(); + + extern const char *fpm_signal_names[NSIG + 1]; + |