commit 00a9d9a57fec3f05ab5e649f384bf694073d278a
Author: Elan Ruusamäe <[email protected]>
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

_______________________________________________
pld-cvs-commit mailing list
[email protected]
http://lists.pld-linux.org/mailman/listinfo/pld-cvs-commit

Reply via email to