[packages/php/PHP_5_3] Sync sapi/fpm/fpm PHP 5.4
glen
glen at pld-linux.org
Wed Dec 1 14:42:26 CET 2021
commit 00a9d9a57fec3f05ab5e649f384bf694073d278a
Author: Elan Ruusamäe <glen at pld-linux.org>
Date: Fri Oct 29 12:35:22 2021 +0300
Sync sapi/fpm/fpm PHP 5.4
git diff -w PHP-5.3..PHP-5.4 -I 'Copyright' sapi/fpm/fpm
php-fpm-5.4.patch | 850 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
php.spec | 7 +-
2 files changed, 855 insertions(+), 2 deletions(-)
---
diff --git a/php.spec b/php.spec
index 2b841a3..873316e 100644
--- a/php.spec
+++ b/php.spec
@@ -252,8 +252,10 @@ Patch75: openssl.patch
Patch76: php-bug-61930.patch
Patch77: php-icu64.patch
Patch78: icu69.patch
-Patch79: php-fpm-shm-corruption.patch
-Patch80: bug-81026-CVE-2021-21703.patch
+# diff PHP-5.3..PHP-5.4 sapi/fpm/fpm/fpm_scoreboard.c
+Patch79: php-fpm-5.4.patch
+Patch80: php-fpm-shm-corruption.patch
+Patch81: bug-81026-CVE-2021-21703.patch
# Fixes for security bugs
# https://repo.webtatic.com/yum/centos/5/SRPMS/repoview/php.html
# also from RHEL6/CentOS7
@@ -2168,6 +2170,7 @@ gzip -dc %{SOURCE15} | tar xf - -C sapi/
%patch78 -p1
%patch79 -p1
%patch80 -p1
+%patch81 -p1
%patch220 -p1
%patch221 -p1
diff --git a/php-fpm-5.4.patch b/php-fpm-5.4.patch
new file mode 100644
index 0000000..15009b5
--- /dev/null
+++ b/php-fpm-5.4.patch
@@ -0,0 +1,850 @@
+diff --git a/sapi/fpm/fpm/events/epoll.c b/sapi/fpm/fpm/events/epoll.c
+index c9c7f1fd6d..b55cb44b15 100644
+--- a/sapi/fpm/fpm/events/epoll.c
++++ b/sapi/fpm/fpm/events/epoll.c
+@@ -46,7 +46,7 @@ static struct fpm_event_module_s epoll_module = {
+
+ static struct epoll_event *epollfds = NULL;
+ static int nepollfds = 0;
+-static int epollfd = 0;
++static int epollfd = -1;
+
+ #endif /* HAVE_EPOLL */
+
+@@ -103,6 +103,10 @@ static int fpm_event_epoll_clean() /* {{{ */
+ free(epollfds);
+ epollfds = NULL;
+ }
++ if (epollfd != -1) {
++ close(epollfd);
++ epollfd = -1;
++ }
+
+ nepollfds = 0;
+
+diff --git a/sapi/fpm/fpm/fastcgi.c b/sapi/fpm/fpm/fastcgi.c
+index cf3f098c53..80745a9c7e 100644
+--- a/sapi/fpm/fpm/fastcgi.c
++++ b/sapi/fpm/fpm/fastcgi.c
+@@ -426,8 +426,9 @@ static int fcgi_get_params(fcgi_request *req, unsigned char *p, unsigned char *e
+ char buf[128];
+ char *tmp = buf;
+ size_t buf_size = sizeof(buf);
+- int name_len, val_len;
+- uint eff_name_len;
++ int name_len = 0;
++ int val_len = 0;
++ uint eff_name_len = 0;
+ char *s;
+ int ret = 1;
+ size_t bytes_consumed;
+diff --git a/sapi/fpm/fpm/fpm_children.c b/sapi/fpm/fpm/fpm_children.c
+index 84a9474332..45cc075b42 100644
+--- a/sapi/fpm/fpm/fpm_children.c
++++ b/sapi/fpm/fpm/fpm_children.c
+@@ -251,7 +251,7 @@ void fpm_children_bury() /* {{{ */
+ }
+ zlog(severity, "[pool %s] child %d exited %s after %ld.%06d seconds from start", child->wp->config->name, (int) pid, buf, tv2.tv_sec, (int) tv2.tv_usec);
+ } else {
+- zlog(ZLOG_DEBUG, "[pool %s] child %d has been killed by the process managment after %ld.%06d seconds from start", child->wp->config->name, (int) pid, tv2.tv_sec, (int) tv2.tv_usec);
++ zlog(ZLOG_DEBUG, "[pool %s] child %d has been killed by the process management after %ld.%06d seconds from start", child->wp->config->name, (int) pid, tv2.tv_sec, (int) tv2.tv_usec);
+ }
+
+ fpm_child_close(child, 1 /* in event_loop */);
+diff --git a/sapi/fpm/fpm/fpm_conf.c b/sapi/fpm/fpm/fpm_conf.c
+index 0a8a0e37e3..103a830389 100644
+--- a/sapi/fpm/fpm/fpm_conf.c
++++ b/sapi/fpm/fpm/fpm_conf.c
+@@ -45,6 +45,10 @@
+ #include "fpm_log.h"
+ #include "fpm_events.h"
+ #include "zlog.h"
++#ifdef HAVE_SYSTEMD
++#include "fpm_systemd.h"
++#endif
++
+
+ #define STR2STR(a) (a ? a : "undefined")
+ #define BOOL2STR(a) (a ? "yes" : "no")
+@@ -73,6 +77,10 @@ struct fpm_global_config_s fpm_global_config = {
+ #endif
+ .process_max = 0,
+ .process_priority = 64, /* 64 means unset */
++#ifdef HAVE_SYSTEMD
++ .systemd_watchdog = 0,
++ .systemd_interval = -1, /* -1 means not set */
++#endif
+ };
+ static struct fpm_worker_pool_s *current_wp = NULL;
+ static int ini_recursion = 0;
+@@ -100,6 +108,9 @@ static struct ini_value_parser_s ini_fpm_global_options[] = {
+ { "rlimit_files", &fpm_conf_set_integer, GO(rlimit_files) },
+ { "rlimit_core", &fpm_conf_set_rlimit_core, GO(rlimit_core) },
+ { "events.mechanism", &fpm_conf_set_string, GO(events_mechanism) },
++#ifdef HAVE_SYSTEMD
++ { "systemd_interval", &fpm_conf_set_time, GO(systemd_interval) },
++#endif
+ { 0, 0, 0 }
+ };
+
+@@ -137,6 +148,7 @@ static struct ini_value_parser_s ini_fpm_pool_options[] = {
+ { "chroot", &fpm_conf_set_string, WPO(chroot) },
+ { "chdir", &fpm_conf_set_string, WPO(chdir) },
+ { "catch_workers_output", &fpm_conf_set_boolean, WPO(catch_workers_output) },
++ { "clear_env", &fpm_conf_set_boolean, WPO(clear_env) },
+ { "security.limit_extensions", &fpm_conf_set_string, WPO(security_limit_extensions) },
+ { 0, 0, 0 }
+ };
+@@ -592,6 +604,7 @@ static void *fpm_worker_pool_config_alloc() /* {{{ */
+ wp->config->listen_backlog = FPM_BACKLOG_DEFAULT;
+ wp->config->pm_process_idle_timeout = 10; /* 10s by default */
+ wp->config->process_priority = 64; /* 64 means unset */
++ wp->config->clear_env = 1;
+
+ if (!fpm_worker_all_pools) {
+ fpm_worker_all_pools = wp;
+@@ -686,7 +699,7 @@ static int fpm_evaluate_full_path(char **path, struct fpm_worker_pool_s *wp, cha
+ if (tmp != NULL) {
+
+ if (tmp != *path) {
+- zlog(ZLOG_ERROR, "'$prefix' must be use at the begining of the value");
++ zlog(ZLOG_ERROR, "'$prefix' must be use at the beginning of the value");
+ return -1;
+ }
+
+@@ -1056,6 +1069,9 @@ static int fpm_conf_process_all_pools() /* {{{ */
+ }
+ }
+ for (kv = wp->config->php_admin_values; kv; kv = kv->next) {
++ if (!strcasecmp(kv->key, "error_log") && !strcasecmp(kv->value, "syslog")) {
++ continue;
++ }
+ for (p = options; *p; p++) {
+ if (!strcasecmp(kv->key, *p)) {
+ fpm_evaluate_full_path(&kv->value, wp, NULL, 0);
+@@ -1152,6 +1168,12 @@ static int fpm_conf_post_process(int force_daemon TSRMLS_DC) /* {{{ */
+ fpm_global_config.error_log = strdup("log/php-fpm.log");
+ }
+
++#ifdef HAVE_SYSTEMD
++ if (0 > fpm_systemd_conf()) {
++ return -1;
++ }
++#endif
++
+ #ifdef HAVE_SYSLOG_H
+ if (!fpm_global_config.syslog_ident) {
+ fpm_global_config.syslog_ident = strdup("php-fpm");
+@@ -1540,6 +1562,9 @@ static void fpm_conf_dump() /* {{{ */
+ zlog(ZLOG_NOTICE, "\trlimit_files = %d", fpm_global_config.rlimit_files);
+ zlog(ZLOG_NOTICE, "\trlimit_core = %d", fpm_global_config.rlimit_core);
+ zlog(ZLOG_NOTICE, "\tevents.mechanism = %s", fpm_event_machanism_name());
++#ifdef HAVE_SYSTEMD
++ zlog(ZLOG_NOTICE, "\tsystemd_interval = %ds", fpm_global_config.systemd_interval/1000);
++#endif
+ zlog(ZLOG_NOTICE, " ");
+
+ for (wp = fpm_worker_all_pools; wp; wp = wp->next) {
+@@ -1580,6 +1605,7 @@ static void fpm_conf_dump() /* {{{ */
+ zlog(ZLOG_NOTICE, "\tchroot = %s", STR2STR(wp->config->chroot));
+ zlog(ZLOG_NOTICE, "\tchdir = %s", STR2STR(wp->config->chdir));
+ zlog(ZLOG_NOTICE, "\tcatch_workers_output = %s", BOOL2STR(wp->config->catch_workers_output));
++ zlog(ZLOG_NOTICE, "\tclear_env = %s", BOOL2STR(wp->config->clear_env));
+ zlog(ZLOG_NOTICE, "\tsecurity.limit_extensions = %s", wp->config->security_limit_extensions);
+
+ for (kv = wp->config->env; kv; kv = kv->next) {
+diff --git a/sapi/fpm/fpm/fpm_conf.h b/sapi/fpm/fpm/fpm_conf.h
+index dc54133d43..19bd7ff1f8 100644
+--- a/sapi/fpm/fpm/fpm_conf.h
++++ b/sapi/fpm/fpm/fpm_conf.h
+@@ -40,6 +40,10 @@ struct fpm_global_config_s {
+ int rlimit_files;
+ int rlimit_core;
+ char *events_mechanism;
++#ifdef HAVE_SYSTEMD
++ int systemd_watchdog;
++ int systemd_interval;
++#endif
+ };
+
+ extern struct fpm_global_config_s fpm_global_config;
+@@ -79,6 +83,7 @@ struct fpm_worker_pool_config_s {
+ char *chroot;
+ char *chdir;
+ int catch_workers_output;
++ int clear_env;
+ char *security_limit_extensions;
+ struct key_value_s *env;
+ struct key_value_s *php_admin_values;
+diff --git a/sapi/fpm/fpm/fpm_env.c b/sapi/fpm/fpm/fpm_env.c
+index 6b64fedfec..2ff0bdc0e4 100644
+--- a/sapi/fpm/fpm/fpm_env.c
++++ b/sapi/fpm/fpm/fpm_env.c
+@@ -143,7 +143,9 @@ int fpm_env_init_child(struct fpm_worker_pool_s *wp) /* {{{ */
+ fpm_env_setproctitle(title);
+ efree(title);
+
++ if (wp->config->clear_env) {
+ clearenv();
++ }
+
+ for (kv = wp->config->env; kv; kv = kv->next) {
+ setenv(kv->key, kv->value, 1);
+diff --git a/sapi/fpm/fpm/fpm_events.c b/sapi/fpm/fpm/fpm_events.c
+index d5835f0f7e..ce5d543f9b 100644
+--- a/sapi/fpm/fpm/fpm_events.c
++++ b/sapi/fpm/fpm/fpm_events.c
+@@ -29,6 +29,10 @@
+ #include "events/port.h"
+ #include "events/kqueue.h"
+
++#ifdef HAVE_SYSTEMD
++#include "fpm_systemd.h"
++#endif
++
+ #define fpm_event_set_timeout(ev, now) timeradd(&(now), &(ev)->frequency, &(ev)->timeout);
+
+ static void fpm_event_cleanup(int which, void *arg);
+@@ -361,6 +365,10 @@ void fpm_event_loop(int err) /* {{{ */
+
+ zlog(ZLOG_DEBUG, "%zu bytes have been reserved in SHM", fpm_shm_get_size_allocated());
+ zlog(ZLOG_NOTICE, "ready to handle connections");
++
++#ifdef HAVE_SYSTEMD
++ fpm_systemd_heartbeat(NULL, 0, NULL);
++#endif
+ }
+
+ while (1) {
+diff --git a/sapi/fpm/fpm/fpm_main.c b/sapi/fpm/fpm/fpm_main.c
+index 6ce8c43fa7..56a06f90ee 100644
+--- a/sapi/fpm/fpm/fpm_main.c
++++ b/sapi/fpm/fpm/fpm_main.c
+@@ -375,12 +375,16 @@ static const http_error http_error_codes[] = {
+ {413, "Request Entity Too Large"},
+ {414, "Request-URI Too Large"},
+ {415, "Unsupported Media Type"},
++ {428, "Precondition Required"},
++ {429, "Too Many Requests"},
++ {431, "Request Header Fields Too Large"},
+ {500, "Internal Server Error"},
+ {501, "Not Implemented"},
+ {502, "Bad Gateway"},
+ {503, "Service Unavailable"},
+ {504, "Gateway Time-out"},
+ {505, "HTTP Version not supported"},
++ {511, "Network Authentication Required"},
+ {0, NULL}
+ };
+
+@@ -561,7 +565,6 @@ void cgi_php_import_environment_variables(zval *array_ptr TSRMLS_DC)
+ {
+ fcgi_request *request;
+ HashPosition pos;
+- int magic_quotes_gpc;;
+ char *var, **val;
+ uint var_len;
+ ulong idx;
+@@ -594,13 +597,8 @@ void cgi_php_import_environment_variables(zval *array_ptr TSRMLS_DC)
+ php_php_import_environment_variables(array_ptr TSRMLS_CC);
+
+ request = (fcgi_request*) SG(server_context);
+- magic_quotes_gpc = PG(magic_quotes_gpc);
+ filter_arg = (array_ptr == PG(http_globals)[TRACK_VARS_ENV])?PARSE_ENV:PARSE_SERVER;
+
+- /* turn off magic_quotes while importing environment variables */
+- if (magic_quotes_gpc) {
+- zend_alter_ini_entry_ex("magic_quotes_gpc", sizeof("magic_quotes_gpc"), "0", 1, ZEND_INI_SYSTEM, ZEND_INI_STAGE_ACTIVATE, 1 TSRMLS_CC);
+- }
+ for (zend_hash_internal_pointer_reset_ex(request->env, &pos);
+ zend_hash_get_current_key_ex(request->env, &var, &var_len, &idx, 0, &pos) == HASH_KEY_IS_STRING &&
+ zend_hash_get_current_data_ex(request->env, (void **) &val, &pos) == SUCCESS;
+@@ -612,9 +610,6 @@ void cgi_php_import_environment_variables(zval *array_ptr TSRMLS_DC)
+ php_register_variable_safe(var, *val, new_val_len, array_ptr TSRMLS_CC);
+ }
+ }
+- if (magic_quotes_gpc) {
+- zend_alter_ini_entry_ex("magic_quotes_gpc", sizeof("magic_quotes_gpc"), "1", 1, ZEND_INI_SYSTEM, ZEND_INI_STAGE_ACTIVATE, 1 TSRMLS_CC);
+- }
+ }
+
+ static void sapi_cgi_register_variables(zval *track_vars_array TSRMLS_DC)
+@@ -944,7 +939,6 @@ static void php_cgi_usage(char *argv0)
+ " force to stay in foreground, and ignore daemonize option from config file\n"
+ " -R, --allow-to-run-as-root\n"
+ " Allow pool to run as root (disabled by default)\n",
+-
+ prog, PHP_PREFIX);
+ }
+ /* }}} */
+@@ -1104,7 +1098,7 @@ static void init_request_info(TSRMLS_D)
+
+ #define APACHE_PROXY_FCGI_PREFIX "proxy:fcgi://"
+ /* Fix proxy URLs in SCRIPT_FILENAME generated by Apache mod_proxy_fcgi:
+- * proxy:fcgi://localhost:9000/some-dir/info.php/test
++ * proxy:fcgi://localhost:9000/some-dir/info.php/test?foo=bar
+ * should be changed to:
+ * /some-dir/info.php/test
+ * See: http://bugs.php.net/bug.php?id=54152
+@@ -1124,6 +1118,11 @@ static void init_request_info(TSRMLS_D)
+ memmove(env_script_filename, p, strlen(p) + 1);
+ apache_was_here = 1;
+ }
++ /* ignore query string if sent by Apache (RewriteRule) */
++ p = strchr(env_script_filename, '?');
++ if (p) {
++ *p =0;
++ }
+ }
+
+ if (CGIG(fix_pathinfo)) {
+@@ -1143,13 +1142,16 @@ static void init_request_info(TSRMLS_D)
+ TRANSLATE_SLASHES(env_document_root);
+ }
+
+- if (env_path_translated != NULL && env_redirect_url != NULL &&
++ if (!apache_was_here && env_path_translated != NULL && env_redirect_url != NULL &&
+ env_path_translated != script_path_translated &&
+ strcmp(env_path_translated, script_path_translated) != 0) {
+ /*
+ * pretty much apache specific. If we have a redirect_url
+ * then our script_filename and script_name point to the
+ * php executable
++ * we don't want to do this for the new mod_proxy_fcgi approach,
++ * where redirect_url may also exist but the below will break
++ * with rewrites to PATH_INFO, hence the !apache_was_here check
+ */
+ script_path_translated = env_path_translated;
+ /* we correct SCRIPT_NAME now in case we don't have PATH_INFO */
+@@ -1324,7 +1326,7 @@ static void init_request_info(TSRMLS_D)
+ efree(pt);
+ }
+ } else {
+- /* make sure path_info/translated are empty */
++ /* make sure original values are remembered in ORIG_ copies if we've changed them */
+ if (!orig_script_filename ||
+ (script_path_translated != orig_script_filename &&
+ strcmp(script_path_translated, orig_script_filename) != 0)) {
+@@ -1333,7 +1335,9 @@ static void init_request_info(TSRMLS_D)
+ }
+ script_path_translated = _sapi_cgibin_putenv("SCRIPT_FILENAME", script_path_translated TSRMLS_CC);
+ }
+- if (env_redirect_url) {
++ if (!apache_was_here && env_redirect_url) {
++ /* if we used PATH_TRANSLATED to work around Apache mod_fastcgi (but not mod_proxy_fcgi,
++ * hence !apache_was_here) weirdness, strip info accordingly */
+ if (orig_path_info) {
+ _sapi_cgibin_putenv("ORIG_PATH_INFO", orig_path_info TSRMLS_CC);
+ _sapi_cgibin_putenv("PATH_INFO", NULL TSRMLS_CC);
+@@ -1512,7 +1516,7 @@ PHP_FUNCTION(fastcgi_finish_request) /* {{{ */
+
+ if (request->fd >= 0) {
+
+- php_end_ob_buffers(1 TSRMLS_CC);
++ php_output_end_all(TSRMLS_C);
+ php_header(TSRMLS_C);
+
+ fcgi_flush(request, 1);
+@@ -1548,7 +1552,7 @@ static zend_module_entry cgi_module_entry = {
+ int main(int argc, char *argv[])
+ {
+ int exit_status = FPM_EXIT_OK;
+- int cgi = 0, c;
++ int cgi = 0, c, use_extended_info = 0;
+ zend_file_handle file_handle;
+
+ /* temporary locals */
+@@ -1573,8 +1577,6 @@ int main(int argc, char *argv[])
+ int php_information = 0;
+ int php_allow_to_run_as_root = 0;
+
+- fcgi_init();
+-
+ #ifdef HAVE_SIGNAL_H
+ #if defined(SIGPIPE) && defined(SIG_IGN)
+ signal(SIGPIPE, SIG_IGN); /* ignore SIGPIPE in standalone mode so
+@@ -1593,6 +1595,9 @@ int main(int argc, char *argv[])
+
+ sapi_startup(&cgi_sapi_module);
+ cgi_sapi_module.php_ini_path_override = NULL;
++ cgi_sapi_module.php_ini_ignore_cwd = 1;
++
++ fcgi_init();
+
+ #ifdef PHP_WIN32
+ _fmode = _O_BINARY; /* sets default for file streams to binary */
+@@ -1659,7 +1664,7 @@ int main(int argc, char *argv[])
+ break;
+
+ case 'e': /* enable extended info output */
+- CG(compiler_options) |= ZEND_COMPILE_EXTENDED_INFO;
++ use_extended_info = 1;
+ break;
+
+ case 't':
+@@ -1668,7 +1673,6 @@ int main(int argc, char *argv[])
+
+ case 'm': /* list compiled in modules */
+ cgi_sapi_module.startup(&cgi_sapi_module);
+- php_output_startup();
+ php_output_activate(TSRMLS_C);
+ SG(headers_sent) = 1;
+ php_printf("[PHP Modules]\n");
+@@ -1676,7 +1680,8 @@ int main(int argc, char *argv[])
+ php_printf("\n[Zend Modules]\n");
+ print_extensions(TSRMLS_C);
+ php_printf("\n");
+- php_end_ob_buffers(1 TSRMLS_CC);
++ php_output_end_all(TSRMLS_C);
++ php_output_deactivate(TSRMLS_C);
+ fcgi_shutdown();
+ exit_status = FPM_EXIT_OK;
+ goto out;
+@@ -1701,11 +1706,11 @@ int main(int argc, char *argv[])
+ case 'h':
+ case '?':
+ cgi_sapi_module.startup(&cgi_sapi_module);
+- php_output_startup();
+ php_output_activate(TSRMLS_C);
+ SG(headers_sent) = 1;
+ php_cgi_usage(argv[0]);
+- php_end_ob_buffers(1 TSRMLS_CC);
++ php_output_end_all(TSRMLS_C);
++ php_output_deactivate(TSRMLS_C);
+ fcgi_shutdown();
+ exit_status = (c == 'h') ? FPM_EXIT_OK : FPM_EXIT_USAGE;
+ goto out;
+@@ -1749,16 +1754,16 @@ int main(int argc, char *argv[])
+ goto out;
+ }
+
+- /* No other args are permitted here as there is not interactive mode */
++ /* No other args are permitted here as there is no interactive mode */
+ if (argc != php_optind) {
+ cgi_sapi_module.startup(&cgi_sapi_module);
+- php_output_startup();
+ php_output_activate(TSRMLS_C);
+ SG(headers_sent) = 1;
+ php_cgi_usage(argv[0]);
+- php_end_ob_buffers(1 TSRMLS_CC);
+- exit_status = FPM_EXIT_USAGE;
++ php_output_end_all(TSRMLS_C);
++ php_output_deactivate(TSRMLS_C);
+ fcgi_shutdown();
++ exit_status = FPM_EXIT_USAGE;
+ goto out;
+ }
+
+@@ -1780,6 +1785,10 @@ int main(int argc, char *argv[])
+ return FPM_EXIT_SOFTWARE;
+ }
+
++ if (use_extended_info) {
++ CG(compiler_options) |= ZEND_COMPILE_EXTENDED_INFO;
++ }
++
+ /* check force_cgi after startup, so we have proper output */
+ if (cgi && CGIG(force_redirect)) {
+ /* Apache will generate REDIRECT_STATUS,
+diff --git a/sapi/fpm/fpm/fpm_php_trace.c b/sapi/fpm/fpm/fpm_php_trace.c
+index cd97aebb33..d95d66a754 100644
+--- a/sapi/fpm/fpm/fpm_php_trace.c
++++ b/sapi/fpm/fpm/fpm_php_trace.c
+@@ -26,6 +26,7 @@
+ #include "fpm_children.h"
+ #include "fpm_worker_pool.h"
+ #include "fpm_process_ctl.h"
++#include "fpm_scoreboard.h"
+
+ #include "zlog.h"
+
+@@ -137,6 +138,7 @@ static int fpm_php_trace_dump(struct fpm_child_s *child, FILE *slowlog TSRMLS_DC
+ void fpm_php_trace(struct fpm_child_s *child) /* {{{ */
+ {
+ TSRMLS_FETCH();
++ fpm_scoreboard_update(0, 0, 0, 0, 0, 0, 1, FPM_SCOREBOARD_ACTION_SET, child->wp->scoreboard);
+ FILE *slowlog;
+
+ zlog(ZLOG_NOTICE, "about to trace %d", (int) child->pid);
+diff --git a/sapi/fpm/fpm/fpm_process_ctl.c b/sapi/fpm/fpm/fpm_process_ctl.c
+index 7840d17f8b..76ea4d358e 100644
+--- a/sapi/fpm/fpm/fpm_process_ctl.c
++++ b/sapi/fpm/fpm/fpm_process_ctl.c
+@@ -353,7 +353,7 @@ static void fpm_pctl_perform_idle_server_maintenance(struct timeval *now) /* {{{
+ #endif
+ }
+ }
+- fpm_scoreboard_update(idle, active, cur_lq, -1, -1, -1, FPM_SCOREBOARD_ACTION_SET, wp->scoreboard);
++ fpm_scoreboard_update(idle, active, cur_lq, -1, -1, -1, 0, FPM_SCOREBOARD_ACTION_SET, wp->scoreboard);
+
+ /* this is specific to PM_STYLE_ONDEMAND */
+ if (wp->config->pm == PM_STYLE_ONDEMAND) {
+@@ -388,7 +388,7 @@ static void fpm_pctl_perform_idle_server_maintenance(struct timeval *now) /* {{{
+ if (idle < wp->config->pm_min_spare_servers) {
+ if (wp->running_children >= wp->config->pm_max_children) {
+ if (!wp->warn_max_children) {
+- fpm_scoreboard_update(0, 0, 0, 0, 0, 1, FPM_SCOREBOARD_ACTION_INC, wp->scoreboard);
++ fpm_scoreboard_update(0, 0, 0, 0, 0, 1, 0, FPM_SCOREBOARD_ACTION_INC, wp->scoreboard);
+ zlog(ZLOG_WARNING, "[pool %s] server reached pm.max_children setting (%d), consider raising it", wp->config->name, wp->config->pm_max_children);
+ wp->warn_max_children = 1;
+ }
+@@ -407,7 +407,7 @@ static void fpm_pctl_perform_idle_server_maintenance(struct timeval *now) /* {{{
+ children_to_fork = MIN(children_to_fork, wp->config->pm_max_children - wp->running_children);
+ if (children_to_fork <= 0) {
+ if (!wp->warn_max_children) {
+- fpm_scoreboard_update(0, 0, 0, 0, 0, 1, FPM_SCOREBOARD_ACTION_INC, wp->scoreboard);
++ fpm_scoreboard_update(0, 0, 0, 0, 0, 1, 0, FPM_SCOREBOARD_ACTION_INC, wp->scoreboard);
+ zlog(ZLOG_WARNING, "[pool %s] server reached pm.max_children setting (%d), consider raising it", wp->config->name, wp->config->pm_max_children);
+ wp->warn_max_children = 1;
+ }
+@@ -511,7 +511,7 @@ void fpm_pctl_on_socket_accept(struct fpm_event_s *ev, short which, void *arg) /
+
+ if (wp->running_children >= wp->config->pm_max_children) {
+ if (!wp->warn_max_children) {
+- fpm_scoreboard_update(0, 0, 0, 0, 0, 1, FPM_SCOREBOARD_ACTION_INC, wp->scoreboard);
++ fpm_scoreboard_update(0, 0, 0, 0, 0, 1, 0, FPM_SCOREBOARD_ACTION_INC, wp->scoreboard);
+ zlog(ZLOG_WARNING, "[pool %s] server reached max_children setting (%d), consider raising it", wp->config->name, wp->config->pm_max_children);
+ wp->warn_max_children = 1;
+ }
+diff --git a/sapi/fpm/fpm/fpm_request.c b/sapi/fpm/fpm/fpm_request.c
+index 28332d0a92..bf431a08d0 100644
+--- a/sapi/fpm/fpm/fpm_request.c
++++ b/sapi/fpm/fpm/fpm_request.c
+@@ -54,7 +54,7 @@ void fpm_request_accepting() /* {{{ */
+ fpm_scoreboard_proc_release(proc);
+
+ /* idle++, active-- */
+- fpm_scoreboard_update(1, -1, 0, 0, 0, 0, FPM_SCOREBOARD_ACTION_INC, NULL);
++ fpm_scoreboard_update(1, -1, 0, 0, 0, 0, 0, FPM_SCOREBOARD_ACTION_INC, NULL);
+ }
+ /* }}} */
+
+@@ -98,7 +98,7 @@ void fpm_request_reading_headers() /* {{{ */
+ fpm_scoreboard_proc_release(proc);
+
+ /* idle--, active++, request++ */
+- fpm_scoreboard_update(-1, 1, 0, 0, 1, 0, FPM_SCOREBOARD_ACTION_INC, NULL);
++ fpm_scoreboard_update(-1, 1, 0, 0, 1, 0, 0, FPM_SCOREBOARD_ACTION_INC, NULL);
+ }
+ /* }}} */
+
+diff --git a/sapi/fpm/fpm/fpm_scoreboard.c b/sapi/fpm/fpm/fpm_scoreboard.c
+index 4222f6037c..24463a90dd 100644
+--- a/sapi/fpm/fpm/fpm_scoreboard.c
++++ b/sapi/fpm/fpm/fpm_scoreboard.c
+@@ -73,7 +73,7 @@ int fpm_scoreboard_init_main() /* {{{ */
+ }
+ /* }}} */
+
+-void fpm_scoreboard_update(int idle, int active, int lq, int lq_len, int requests, int max_children_reached, int action, struct fpm_scoreboard_s *scoreboard) /* {{{ */
++void fpm_scoreboard_update(int idle, int active, int lq, int lq_len, int requests, int max_children_reached, int slow_rq, int action, struct fpm_scoreboard_s *scoreboard) /* {{{ */
+ {
+ if (!scoreboard) {
+ scoreboard = fpm_scoreboard;
+@@ -110,6 +110,9 @@ void fpm_scoreboard_update(int idle, int active, int lq, int lq_len, int request
+ if (max_children_reached >= 0) {
+ scoreboard->max_children_reached = max_children_reached;
+ }
++ if (slow_rq > 0) {
++ scoreboard->slow_rq += slow_rq;
++ }
+ } else {
+ if (scoreboard->idle + idle > 0) {
+ scoreboard->idle += idle;
+diff --git a/sapi/fpm/fpm/fpm_scoreboard.h b/sapi/fpm/fpm/fpm_scoreboard.h
+index 136ea481a4..f58a28737d 100644
+--- a/sapi/fpm/fpm/fpm_scoreboard.h
++++ b/sapi/fpm/fpm/fpm_scoreboard.h
+@@ -64,13 +64,14 @@ struct fpm_scoreboard_s {
+ unsigned int lq_len;
+ unsigned int nprocs;
+ int free_proc;
++ unsigned long int slow_rq;
+ struct fpm_scoreboard_proc_s *procs[];
+ };
+
+ int fpm_scoreboard_init_main();
+ int fpm_scoreboard_init_child(struct fpm_worker_pool_s *wp);
+
+-void fpm_scoreboard_update(int idle, int active, int lq, int lq_len, int requests, int max_children_reached, int action, struct fpm_scoreboard_s *scoreboard);
++void fpm_scoreboard_update(int idle, int active, int lq, int lq_len, int requests, int max_children_reached, int slow_rq, int action, struct fpm_scoreboard_s *scoreboard);
+ struct fpm_scoreboard_s *fpm_scoreboard_get();
+ struct fpm_scoreboard_proc_s *fpm_scoreboard_proc_get(struct fpm_scoreboard_s *scoreboard, int child_index);
+
+diff --git a/sapi/fpm/fpm/fpm_sockets.c b/sapi/fpm/fpm/fpm_sockets.c
+index 3dcad4e70f..e056565ea4 100644
+--- a/sapi/fpm/fpm/fpm_sockets.c
++++ b/sapi/fpm/fpm/fpm_sockets.c
+@@ -362,7 +362,7 @@ int fpm_sockets_init_main() /* {{{ */
+ }
+
+ if (wp->listen_address_domain == FPM_AF_INET && fpm_socket_get_listening_queue(wp->listening_socket, NULL, &lq_len) >= 0) {
+- fpm_scoreboard_update(-1, -1, -1, (int)lq_len, -1, -1, FPM_SCOREBOARD_ACTION_SET, wp->scoreboard);
++ fpm_scoreboard_update(-1, -1, -1, (int)lq_len, -1, -1, 0, FPM_SCOREBOARD_ACTION_SET, wp->scoreboard);
+ }
+ }
+
+@@ -405,7 +405,19 @@ int fpm_socket_get_listening_queue(int sock, unsigned *cur_lq, unsigned *max_lq)
+ zlog(ZLOG_SYSERROR, "failed to retrieve TCP_INFO for socket");
+ return -1;
+ }
++#if defined(__FreeBSD__)
++ if (info.__tcpi_sacked == 0) {
++ return -1;
++ }
++
++ if (cur_lq) {
++ *cur_lq = info.__tcpi_unacked;
++ }
+
++ if (max_lq) {
++ *max_lq = info.__tcpi_sacked;
++ }
++#else
+ /* kernel >= 2.6.24 return non-zero here, that means operation is supported */
+ if (info.tcpi_sacked == 0) {
+ return -1;
+@@ -418,6 +430,7 @@ int fpm_socket_get_listening_queue(int sock, unsigned *cur_lq, unsigned *max_lq)
+ if (max_lq) {
+ *max_lq = info.tcpi_sacked;
+ }
++#endif
+
+ return 0;
+ }
+@@ -474,6 +487,7 @@ int fpm_socket_unix_test_connect(struct sockaddr_un *sock, size_t socklen) /* {{
+ }
+
+ if (connect(fd, (struct sockaddr *)sock, socklen) == -1) {
++ close(fd);
+ return -1;
+ }
+
+diff --git a/sapi/fpm/fpm/fpm_status.c b/sapi/fpm/fpm/fpm_status.c
+index 7bad5951d8..2363b57f80 100644
+--- a/sapi/fpm/fpm/fpm_status.c
++++ b/sapi/fpm/fpm/fpm_status.c
+@@ -158,6 +158,7 @@ int fpm_status_handle_request(TSRMLS_D) /* {{{ */
+ "<tr><th>total processes</th><td>%d</td></tr>\n"
+ "<tr><th>max active processes</th><td>%d</td></tr>\n"
+ "<tr><th>max children reached</th><td>%u</td></tr>\n"
++ "<tr><th>slow requests</th><td>%lu</td></tr>\n"
+ "</table>\n";
+
+ if (!full) {
+@@ -228,7 +229,8 @@ int fpm_status_handle_request(TSRMLS_D) /* {{{ */
+ "<active-processes>%d</active-processes>\n"
+ "<total-processes>%d</total-processes>\n"
+ "<max-active-processes>%d</max-active-processes>\n"
+- "<max-children-reached>%u</max-children-reached>\n";
++ "<max-children-reached>%u</max-children-reached>\n"
++ "<slow-requests>%lu</slow-requests>\n";
+
+ if (!full) {
+ short_post = "</status>";
+@@ -277,7 +279,8 @@ int fpm_status_handle_request(TSRMLS_D) /* {{{ */
+ "\"active processes\":%d,"
+ "\"total processes\":%d,"
+ "\"max active processes\":%d,"
+- "\"max children reached\":%u";
++ "\"max children reached\":%u,"
++ "\"slow requests\":%lu";
+
+ if (!full) {
+ short_post = "}";
+@@ -326,7 +329,8 @@ int fpm_status_handle_request(TSRMLS_D) /* {{{ */
+ "active processes: %d\n"
+ "total processes: %d\n"
+ "max active processes: %d\n"
+- "max children reached: %u\n";
++ "max children reached: %u\n"
++ "slow requests: %lu\n";
+
+ if (full) {
+ full_syntax =
+@@ -367,7 +371,8 @@ int fpm_status_handle_request(TSRMLS_D) /* {{{ */
+ scoreboard.active,
+ scoreboard.idle + scoreboard.active,
+ scoreboard.active_max,
+- scoreboard.max_children_reached);
++ scoreboard.max_children_reached,
++ scoreboard.slow_rq);
+
+ PUTS(buffer);
+ efree(buffer);
+@@ -378,7 +383,8 @@ int fpm_status_handle_request(TSRMLS_D) /* {{{ */
+
+ /* no need to test the var 'full' */
+ if (full_syntax) {
+- int i, len, first;
++ int i, first;
++ size_t len;
+ char *query_string;
+ struct timeval duration, now;
+ #ifdef HAVE_FPM_LQ
+diff --git a/sapi/fpm/fpm/fpm_stdio.c b/sapi/fpm/fpm/fpm_stdio.c
+index 10b867d00a..7bcf785238 100644
+--- a/sapi/fpm/fpm/fpm_stdio.c
++++ b/sapi/fpm/fpm/fpm_stdio.c
+@@ -268,7 +268,11 @@ int fpm_stdio_open_error_log(int reopen) /* {{{ */
+ if (!strcasecmp(fpm_global_config.error_log, "syslog")) {
+ openlog(fpm_global_config.syslog_ident, LOG_PID | LOG_CONS, fpm_global_config.syslog_facility);
+ fpm_globals.error_log_fd = ZLOG_SYSLOG;
++#if HAVE_UNISTD_H
++ if (fpm_global_config.daemonize || !isatty(STDERR_FILENO)) {
++#else
+ if (fpm_global_config.daemonize) {
++#endif
+ zlog_set_fd(fpm_globals.error_log_fd);
+ }
+ return 0;
+@@ -291,7 +295,11 @@ int fpm_stdio_open_error_log(int reopen) /* {{{ */
+ fd = fpm_globals.error_log_fd; /* for FD_CLOSEXEC to work */
+ } else {
+ fpm_globals.error_log_fd = fd;
++#if HAVE_UNISTD_H
++ if (fpm_global_config.daemonize || !isatty(STDERR_FILENO)) {
++#else
+ if (fpm_global_config.daemonize) {
++#endif
+ zlog_set_fd(fpm_globals.error_log_fd);
+ }
+ }
+diff --git a/sapi/fpm/fpm/fpm_systemd.c b/sapi/fpm/fpm/fpm_systemd.c
+new file mode 100644
+index 0000000000..c4d7ec15a4
+--- /dev/null
++++ b/sapi/fpm/fpm/fpm_systemd.c
+@@ -0,0 +1,113 @@
++#include "fpm_config.h"
++
++#include <sys/types.h>
++#include <systemd/sd-daemon.h>
++
++#include "fpm.h"
++#include "fpm_clock.h"
++#include "fpm_worker_pool.h"
++#include "fpm_scoreboard.h"
++#include "zlog.h"
++#include "fpm_systemd.h"
++
++
++static void fpm_systemd() /* {{{ */
++{
++ static unsigned long int last=0;
++ struct fpm_worker_pool_s *wp;
++ unsigned long int requests=0, slow_req=0;
++ int active=0, idle=0;
++
++
++ for (wp = fpm_worker_all_pools; wp; wp = wp->next) {
++ if (wp->scoreboard) {
++ active += wp->scoreboard->active;
++ idle += wp->scoreboard->idle;
++ requests += wp->scoreboard->requests;
++ slow_req += wp->scoreboard->slow_rq;
++ }
++ }
++
++/*
++ zlog(ZLOG_DEBUG, "systemd %s (Processes active:%d, idle:%d, Requests:%lu, slow:%lu, Traffic:%.3greq/sec)",
++ fpm_global_config.systemd_watchdog ? "watchdog" : "heartbeat",
++ active, idle, requests, slow_req, ((float)requests - last) * 1000.0 / fpm_global_config.systemd_interval);
++*/
++
++ if (0 > sd_notifyf(0, "READY=1\n%s"
++ "STATUS=Processes active: %d, idle: %d, Requests: %lu, slow: %lu, Traffic: %.3greq/sec",
++ fpm_global_config.systemd_watchdog ? "WATCHDOG=1\n" : "",
++ active, idle, requests, slow_req, ((float)requests - last) * 1000.0 / fpm_global_config.systemd_interval)) {
++ zlog(ZLOG_NOTICE, "failed to notify status to systemd");
++ }
++
++ last = requests;
++}
++/* }}} */
++
++void fpm_systemd_heartbeat(struct fpm_event_s *ev, short which, void *arg) /* {{{ */
++{
++ static struct fpm_event_s heartbeat;
++
++ if (fpm_globals.parent_pid != getpid()) {
++ return; /* sanity check */
++ }
++
++ if (which == FPM_EV_TIMEOUT) {
++ fpm_systemd();
++
++ return;
++ }
++
++ if (0 > sd_notifyf(0, "READY=1\n"
++ "STATUS=Ready to handle connections\n"
++ "MAINPID=%lu",
++ (unsigned long) getpid())) {
++ zlog(ZLOG_WARNING, "failed to notify start to systemd");
++ } else {
++ zlog(ZLOG_DEBUG, "have notify start to systemd");
++ }
++
++ /* first call without setting which to initialize the timer */
++ if (fpm_global_config.systemd_interval > 0) {
++ fpm_event_set_timer(&heartbeat, FPM_EV_PERSIST, &fpm_systemd_heartbeat, NULL);
++ fpm_event_add(&heartbeat, fpm_global_config.systemd_interval);
++ zlog(ZLOG_NOTICE, "systemd monitor interval set to %dms", fpm_global_config.systemd_interval);
++ } else {
++ zlog(ZLOG_NOTICE, "systemd monitor disabled");
++ }
++}
++/* }}} */
++
++int fpm_systemd_conf() /* {{{ */
++{
++ char *watchdog;
++ int interval = 0;
++
++ watchdog = getenv("WATCHDOG_USEC");
++ if (watchdog) {
++ /* usec to msec, and half the configured delay */
++ interval = (int)(atol(watchdog) / 2000L);
++ zlog(ZLOG_DEBUG, "WATCHDOG_USEC=%s, interval=%d", watchdog, interval);
++ }
++
++ if (interval > 1000) {
++ if (fpm_global_config.systemd_interval > 0) {
++ zlog(ZLOG_WARNING, "systemd_interval option ignored");
++ }
++ zlog(ZLOG_NOTICE, "systemd watchdog configured to %.3gsec", (float)interval / 1000.0);
++ fpm_global_config.systemd_watchdog = 1;
++ fpm_global_config.systemd_interval = interval;
++
++ } else if (fpm_global_config.systemd_interval < 0) {
++ /* not set => default value */
++ fpm_global_config.systemd_interval = FPM_SYSTEMD_DEFAULT_HEARTBEAT;
++
++ } else {
++ /* sec to msec */
++ fpm_global_config.systemd_interval *= 1000;
++ }
++ return 0;
++}
++/* }}} */
++
+diff --git a/sapi/fpm/fpm/fpm_systemd.h b/sapi/fpm/fpm/fpm_systemd.h
+new file mode 100644
+index 0000000000..3ee6217717
+--- /dev/null
++++ b/sapi/fpm/fpm/fpm_systemd.h
+@@ -0,0 +1,13 @@
++#ifndef FPM_SYSTEMD_H
++#define FPM_SYSTEMD_H 1
++
++#include "fpm_events.h"
++
++/* 10s (in ms) heartbeat for systemd status */
++#define FPM_SYSTEMD_DEFAULT_HEARTBEAT (10000)
++
++void fpm_systemd_heartbeat(struct fpm_event_s *ev, short which, void *arg);
++int fpm_systemd_conf();
++
++#endif
++
================================================================
---- gitweb:
http://git.pld-linux.org/gitweb.cgi/packages/php.git/commitdiff/8359939cab722919c56e747283a64e725a78dcee
More information about the pld-cvs-commit
mailing list