summaryrefslogtreecommitdiff
path: root/sapi
diff options
context:
space:
mode:
authorJerome Loyet <fat@php.net>2012-05-25 19:15:06 (GMT)
committerJerome Loyet <fat@php.net>2012-05-25 19:15:06 (GMT)
commita28fe034f2d5253e0fbefafc6a7938df9db7319e (patch)
tree5f6107647f777ae94e8dbbdbb986389d010a589d /sapi
parent61a13773bcbf761ecc03faa99877d3cac90529a0 (diff)
downloadphp-a28fe034f2d5253e0fbefafc6a7938df9db7319e.tar.gz
- Fixed bug #62033 (php-fpm exits with status 0 on some failures to start).
Diffstat (limited to 'sapi')
-rw-r--r--sapi/fpm/config.m41
-rw-r--r--sapi/fpm/fpm/fpm.c2
-rw-r--r--sapi/fpm/fpm/fpm.h29
-rw-r--r--sapi/fpm/fpm/fpm_children.c4
-rw-r--r--sapi/fpm/fpm/fpm_main.c43
-rw-r--r--sapi/fpm/fpm/fpm_process_ctl.c4
-rw-r--r--sapi/fpm/fpm/fpm_signals.c12
-rw-r--r--sapi/fpm/fpm/fpm_signals.h3
-rw-r--r--sapi/fpm/fpm/fpm_unix.c68
9 files changed, 135 insertions, 31 deletions
diff --git a/sapi/fpm/config.m4 b/sapi/fpm/config.m4
index 6c860c9..ad46717 100644
--- a/sapi/fpm/config.m4
+++ b/sapi/fpm/config.m4
@@ -16,6 +16,7 @@ AC_DEFUN([AC_FPM_STDLIBS],
AC_CHECK_HEADERS([errno.h fcntl.h stdio.h stdlib.h unistd.h sys/uio.h])
AC_CHECK_HEADERS([sys/select.h sys/socket.h sys/time.h])
AC_CHECK_HEADERS([arpa/inet.h netinet/in.h])
+ AC_CHECK_HEADERS([sysexits.h])
])
AC_DEFUN([AC_FPM_PRCTL],
diff --git a/sapi/fpm/fpm/fpm.c b/sapi/fpm/fpm/fpm.c
index 909902b..176dbaf 100644
--- a/sapi/fpm/fpm/fpm.c
+++ b/sapi/fpm/fpm/fpm.c
@@ -66,7 +66,7 @@ int fpm_init(int argc, char **argv, char *config, char *prefix, char *pid, int t
0 > fpm_event_init_main()) {
if (fpm_globals.test_successful) {
- exit(0);
+ exit(FPM_EXIT_OK);
} else {
zlog(ZLOG_ERROR, "FPM initialization failed");
return -1;
diff --git a/sapi/fpm/fpm/fpm.h b/sapi/fpm/fpm/fpm.h
index 2a69cb2..b0bed0a 100644
--- a/sapi/fpm/fpm/fpm.h
+++ b/sapi/fpm/fpm/fpm.h
@@ -7,6 +7,35 @@
#include <unistd.h>
+#ifdef HAVE_SYSEXITS_H
+#include <sysexits.h>
+#endif
+
+#ifdef EX_OK
+#define FPM_EXIT_OK EX_OK
+#else
+#define FPM_EXIT_OK 0
+#endif
+
+#ifdef EX_USAGE
+#define FPM_EXIT_USAGE EX_USAGE
+#else
+#define FPM_EXIT_USAGE 64
+#endif
+
+#ifdef EX_SOFTWARE
+#define FPM_EXIT_SOFTWARE EX_SOFTWARE
+#else
+#define FPM_EXIT_SOFTWARE 70
+#endif
+
+#ifdef EX_CONFIG
+#define FPM_EXIT_CONFIG EX_CONFIG
+#else
+#define FPM_EXIT_CONFIG 78
+#endif
+
+
int fpm_run(int *max_requests);
int fpm_init(int argc, char **argv, char *config, char *prefix, char *pid, int test_conf, int run_as_root);
diff --git a/sapi/fpm/fpm/fpm_children.c b/sapi/fpm/fpm/fpm_children.c
index 35058b0..84a9474 100644
--- a/sapi/fpm/fpm/fpm_children.c
+++ b/sapi/fpm/fpm/fpm_children.c
@@ -156,7 +156,7 @@ static void fpm_child_init(struct fpm_worker_pool_s *wp) /* {{{ */
0 > fpm_php_init_child(wp)) {
zlog(ZLOG_ERROR, "[pool %s] child failed to initialize", wp->config->name);
- exit(255);
+ exit(FPM_EXIT_SOFTWARE);
}
}
/* }}} */
@@ -198,7 +198,7 @@ void fpm_children_bury() /* {{{ */
restart_child = 0;
}
- if (WEXITSTATUS(status) != 0) {
+ if (WEXITSTATUS(status) != FPM_EXIT_OK) {
severity = ZLOG_WARNING;
}
diff --git a/sapi/fpm/fpm/fpm_main.c b/sapi/fpm/fpm/fpm_main.c
index 130673f..c3fd2bc 100644
--- a/sapi/fpm/fpm/fpm_main.c
+++ b/sapi/fpm/fpm/fpm_main.c
@@ -1528,7 +1528,7 @@ static zend_module_entry cgi_module_entry = {
*/
int main(int argc, char *argv[])
{
- int exit_status = SUCCESS;
+ int exit_status = FPM_EXIT_OK;
int cgi = 0, c, use_extended_info = 0;
zend_file_handle file_handle;
@@ -1659,7 +1659,7 @@ int main(int argc, char *argv[])
php_output_end_all(TSRMLS_C);
php_output_deactivate(TSRMLS_C);
fcgi_shutdown();
- exit_status = 0;
+ exit_status = FPM_EXIT_OK;
goto out;
case 'i': /* php info & quit */
@@ -1680,7 +1680,7 @@ int main(int argc, char *argv[])
php_output_end_all(TSRMLS_C);
php_output_deactivate(TSRMLS_C);
fcgi_shutdown();
- exit_status = 0;
+ exit_status = (c == 'h') ? FPM_EXIT_OK : FPM_EXIT_USAGE;
goto out;
case 'v': /* show php version & quit */
@@ -1688,7 +1688,7 @@ int main(int argc, char *argv[])
if (php_request_startup(TSRMLS_C) == FAILURE) {
SG(server_context) = NULL;
php_module_shutdown(TSRMLS_C);
- return FAILURE;
+ return FPM_EXIT_SOFTWARE;
}
SG(headers_sent) = 1;
SG(request_info).no_headers = 1;
@@ -1700,7 +1700,7 @@ int main(int argc, char *argv[])
#endif
php_request_shutdown((void *) 0);
fcgi_shutdown();
- exit_status = 0;
+ exit_status = FPM_EXIT_OK;
goto out;
}
}
@@ -1711,14 +1711,14 @@ int main(int argc, char *argv[])
if (php_request_startup(TSRMLS_C) == FAILURE) {
SG(server_context) = NULL;
php_module_shutdown(TSRMLS_C);
- return FAILURE;
+ return FPM_EXIT_SOFTWARE;
}
SG(headers_sent) = 1;
SG(request_info).no_headers = 1;
php_print_info(0xFFFFFFFF TSRMLS_CC);
php_request_shutdown((void *) 0);
fcgi_shutdown();
- exit_status = 0;
+ exit_status = FPM_EXIT_OK;
goto out;
}
@@ -1731,7 +1731,7 @@ int main(int argc, char *argv[])
php_output_end_all(TSRMLS_C);
php_output_deactivate(TSRMLS_C);
fcgi_shutdown();
- exit_status = 0;
+ exit_status = FPM_EXIT_USAGE;
goto out;
}
@@ -1750,7 +1750,7 @@ int main(int argc, char *argv[])
#ifdef ZTS
tsrm_shutdown();
#endif
- return FAILURE;
+ return FPM_EXIT_SOFTWARE;
}
if (use_extended_info) {
@@ -1793,14 +1793,23 @@ consult the installation file that came with this distribution, or visit \n\
*/
tsrm_shutdown();
#endif
- return FAILURE;
+ return FPM_EXIT_SOFTWARE;
}
}
if (0 > fpm_init(argc, argv, fpm_config ? fpm_config : CGIG(fpm_config), fpm_prefix, fpm_pid, test_conf, php_allow_to_run_as_root)) {
- return FAILURE;
+
+ if (fpm_global_config.daemonize) {
+ zlog(ZLOG_DEBUG, "Sending SIGUSR2 (error) to parent %d", getppid());
+ kill(getppid(), SIGUSR2);
+ }
+ return FPM_EXIT_CONFIG;
}
+ if (fpm_global_config.daemonize) {
+ zlog(ZLOG_DEBUG, "Sending SIGUSR1 (OK) to parent %d", getppid());
+ kill(getppid(), SIGUSR1);
+ }
fpm_is_running = 1;
fcgi_fd = fpm_run(&max_requests);
@@ -1832,7 +1841,7 @@ consult the installation file that came with this distribution, or visit \n\
fcgi_finish_request(&request, 1);
SG(server_context) = NULL;
php_module_shutdown(TSRMLS_C);
- return FAILURE;
+ return FPM_EXIT_SOFTWARE;
}
/* check if request_method has been sent.
@@ -1920,17 +1929,9 @@ fastcgi_request_done:
php_request_shutdown((void *) 0);
- if (exit_status == 0) {
- exit_status = EG(exit_status);
- }
-
requests++;
if (max_requests && (requests == max_requests)) {
fcgi_finish_request(&request, 1);
- if (max_requests != 1) {
- /* no need to return exit_status of the last request */
- exit_status = 0;
- }
break;
}
/* end of fastcgi loop */
@@ -1944,7 +1945,7 @@ fastcgi_request_done:
free(cgi_sapi_module.ini_entries);
}
} zend_catch {
- exit_status = 255;
+ exit_status = FPM_EXIT_SOFTWARE;
} zend_end_try();
out:
diff --git a/sapi/fpm/fpm/fpm_process_ctl.c b/sapi/fpm/fpm/fpm_process_ctl.c
index e698eb0..7840d17 100644
--- a/sapi/fpm/fpm/fpm_process_ctl.c
+++ b/sapi/fpm/fpm/fpm_process_ctl.c
@@ -71,7 +71,7 @@ static void fpm_pctl_exit() /* {{{ */
fpm_conf_unlink_pid();
fpm_cleanups_run(FPM_CLEANUP_PARENT_EXIT_MAIN);
- exit(0);
+ exit(FPM_EXIT_OK);
}
/* }}} */
@@ -100,7 +100,7 @@ static void fpm_pctl_exec() /* {{{ */
fpm_cleanups_run(FPM_CLEANUP_PARENT_EXEC);
execvp(saved_argv[0], saved_argv);
zlog(ZLOG_SYSERROR, "failed to reload: execvp() failed");
- exit(1);
+ exit(FPM_EXIT_SOFTWARE);
}
/* }}} */
diff --git a/sapi/fpm/fpm/fpm_signals.c b/sapi/fpm/fpm/fpm_signals.c
index 8993a86..656269f 100644
--- a/sapi/fpm/fpm/fpm_signals.c
+++ b/sapi/fpm/fpm/fpm_signals.c
@@ -249,3 +249,15 @@ int fpm_signals_get_fd() /* {{{ */
}
/* }}} */
+void fpm_signals_sighandler_exit_ok(pid_t pid) /* {{{ */
+{
+ exit(FPM_EXIT_OK);
+}
+/* }}} */
+
+void fpm_signals_sighandler_exit_config(pid_t pid) /* {{{ */
+{
+ exit(FPM_EXIT_CONFIG);
+}
+/* }}} */
+
diff --git a/sapi/fpm/fpm/fpm_signals.h b/sapi/fpm/fpm/fpm_signals.h
index eb80fae..13484cb 100644
--- a/sapi/fpm/fpm/fpm_signals.h
+++ b/sapi/fpm/fpm/fpm_signals.h
@@ -11,6 +11,9 @@ int fpm_signals_init_main();
int fpm_signals_init_child();
int fpm_signals_get_fd();
+void fpm_signals_sighandler_exit_ok(pid_t pid);
+void fpm_signals_sighandler_exit_config(pid_t pid);
+
extern const char *fpm_signal_names[NSIG + 1];
#endif
diff --git a/sapi/fpm/fpm/fpm_unix.c b/sapi/fpm/fpm/fpm_unix.c
index fb61d63..1ab8189 100644
--- a/sapi/fpm/fpm/fpm_unix.c
+++ b/sapi/fpm/fpm/fpm_unix.c
@@ -23,6 +23,7 @@
#include "fpm_clock.h"
#include "fpm_stdio.h"
#include "fpm_unix.h"
+#include "fpm_signals.h"
#include "zlog.h"
size_t fpm_pagesize;
@@ -242,18 +243,75 @@ int fpm_unix_init_main() /* {{{ */
fpm_pagesize = getpagesize();
if (fpm_global_config.daemonize) {
- switch (fork()) {
- case -1 :
+ /*
+ * If daemonize, the calling process will die soon
+ * and the master process continues to initialize itself.
+ *
+ * The parent process has then to wait for the master
+ * process to initialize to return a consistent exit
+ * value. For this pupose, the master process will
+ * send USR1 if everything went well and USR2
+ * otherwise.
+ */
+
+ struct sigaction act;
+ struct sigaction oldact_usr1;
+ struct sigaction oldact_usr2;
+ struct timeval tv;
+
+ /*
+ * set sigaction for USR1 before fork
+ * save old sigaction to restore it after
+ * fork in the child process (the master process)
+ */
+ memset(&act, 0, sizeof(act));
+ memset(&act, 0, sizeof(oldact_usr1));
+ act.sa_handler = fpm_signals_sighandler_exit_ok;
+ sigfillset(&act.sa_mask);
+ sigaction(SIGUSR1, &act, &oldact_usr1);
+
+ /*
+ * set sigaction for USR2 before fork
+ * save old sigaction to restore it after
+ * fork in the child process (the master process)
+ */
+ memset(&act, 0, sizeof(act));
+ memset(&act, 0, sizeof(oldact_usr2));
+ act.sa_handler = fpm_signals_sighandler_exit_config;
+ sigfillset(&act.sa_mask);
+ sigaction(SIGUSR2, &act, &oldact_usr2);
+
+ /* then fork */
+ pid_t pid = fork();
+ switch (pid) {
+
+ case -1 : /* error */
zlog(ZLOG_SYSERROR, "failed to daemonize");
return -1;
- case 0 :
+
+ case 0 : /* children */
+ /* restore USR1 and USR2 sigaction */
+ sigaction(SIGUSR1, &oldact_usr1, NULL);
+ sigaction(SIGUSR2, &oldact_usr2, NULL);
break;
- default :
+
+ default : /* parent */
fpm_cleanups_run(FPM_CLEANUP_PARENT_EXIT);
- exit(0);
+
+ /*
+ * wait for 10s before exiting with error
+ * the child is supposed to send USR1 or USR2 to tell the parent
+ * how it goes for it
+ */
+ tv.tv_sec = 10;
+ tv.tv_usec = 0;
+ zlog(ZLOG_DEBUG, "The calling process is waiting for the master process to ping");
+ select(0, NULL, NULL, NULL, &tv);
+ exit(FPM_EXIT_SOFTWARE);
}
}
+ /* continue as a child */
setsid();
if (0 > fpm_clock_init()) {
return -1;