[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