Skip to content

Commit b5eb145

Browse files
author
Jerome Loyet
committed
- Fixed bug #62954 (startup problems fpm / php-fpm)
- Fixed bug #62886 (PHP-FPM may segfault/hang on startup)
1 parent 0bffdd7 commit b5eb145

File tree

7 files changed

+63
-57
lines changed

7 files changed

+63
-57
lines changed

NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ PHP NEWS
3030
- DOM:
3131
. Fixed bug #63015 (Incorrect arginfo for DOMErrorHandler). (Rob)
3232

33+
- FPM:
34+
. Fixed bug #62954 (startup problems fpm / php-fpm). (fat)
35+
. Fixed bug #62886 (PHP-FPM may segfault/hang on startup). (fat)
36+
3337
- OpenSSL:
3438
. Implemented FR #61421 (OpenSSL signature verification missing RMD160,
3539
SHA224, SHA256, SHA384, SHA512). (Mark Jones)

sapi/fpm/fpm/fpm.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ struct fpm_globals_s fpm_globals = {
3939
.test_successful = 0,
4040
.heartbeat = 0,
4141
.run_as_root = 0,
42-
.send_config_signal = 0,
42+
.send_config_pipe = {0, 0},
4343
};
4444

4545
int fpm_init(int argc, char **argv, char *config, char *prefix, char *pid, int test_conf, int run_as_root) /* {{{ */

sapi/fpm/fpm/fpm.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ struct fpm_globals_s {
5555
int test_successful;
5656
int heartbeat;
5757
int run_as_root;
58-
int send_config_signal;
58+
int send_config_pipe[2];
5959
};
6060

6161
extern struct fpm_globals_s fpm_globals;

sapi/fpm/fpm/fpm_main.c

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1799,16 +1799,20 @@ consult the installation file that came with this distribution, or visit \n\
17991799

18001800
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)) {
18011801

1802-
if (fpm_globals.send_config_signal) {
1803-
zlog(ZLOG_DEBUG, "Sending SIGUSR2 (error) to parent %d", getppid());
1804-
kill(getppid(), SIGUSR2);
1802+
if (fpm_globals.send_config_pipe[1]) {
1803+
int writeval = 0;
1804+
zlog(ZLOG_DEBUG, "Sending \"0\" (error) to parent via fd=%d", fpm_globals.send_config_pipe[1]);
1805+
write(fpm_globals.send_config_pipe[1], &writeval, sizeof(writeval));
1806+
close(fpm_globals.send_config_pipe[1]);
18051807
}
18061808
return FPM_EXIT_CONFIG;
18071809
}
18081810

1809-
if (fpm_globals.send_config_signal) {
1810-
zlog(ZLOG_DEBUG, "Sending SIGUSR1 (OK) to parent %d", getppid());
1811-
kill(getppid(), SIGUSR1);
1811+
if (fpm_globals.send_config_pipe[1]) {
1812+
int writeval = 1;
1813+
zlog(ZLOG_DEBUG, "Sending \"1\" (OK) to parent via fd=%d", fpm_globals.send_config_pipe[1]);
1814+
write(fpm_globals.send_config_pipe[1], &writeval, sizeof(writeval));
1815+
close(fpm_globals.send_config_pipe[1]);
18121816
}
18131817
fpm_is_running = 1;
18141818

sapi/fpm/fpm/fpm_signals.c

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -249,15 +249,3 @@ int fpm_signals_get_fd() /* {{{ */
249249
}
250250
/* }}} */
251251

252-
void fpm_signals_sighandler_exit_ok(pid_t pid) /* {{{ */
253-
{
254-
exit(FPM_EXIT_OK);
255-
}
256-
/* }}} */
257-
258-
void fpm_signals_sighandler_exit_config(pid_t pid) /* {{{ */
259-
{
260-
exit(FPM_EXIT_CONFIG);
261-
}
262-
/* }}} */
263-

sapi/fpm/fpm/fpm_signals.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,6 @@ int fpm_signals_init_main();
1111
int fpm_signals_init_child();
1212
int fpm_signals_get_fd();
1313

14-
void fpm_signals_sighandler_exit_ok(pid_t pid);
15-
void fpm_signals_sighandler_exit_config(pid_t pid);
16-
1714
extern const char *fpm_signal_names[NSIG + 1];
1815

1916
#endif

sapi/fpm/fpm/fpm_unix.c

Lines changed: 47 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -262,36 +262,19 @@ int fpm_unix_init_main() /* {{{ */
262262
* The parent process has then to wait for the master
263263
* process to initialize to return a consistent exit
264264
* value. For this pupose, the master process will
265-
* send USR1 if everything went well and USR2
266-
* otherwise.
265+
* send \"1\" into the pipe if everything went well
266+
* and \"0\" otherwise.
267267
*/
268268

269-
struct sigaction act;
270-
struct sigaction oldact_usr1;
271-
struct sigaction oldact_usr2;
272-
struct timeval tv;
273269

274-
/*
275-
* set sigaction for USR1 before fork
276-
* save old sigaction to restore it after
277-
* fork in the child process (the master process)
278-
*/
279-
memset(&act, 0, sizeof(act));
280-
memset(&act, 0, sizeof(oldact_usr1));
281-
act.sa_handler = fpm_signals_sighandler_exit_ok;
282-
sigfillset(&act.sa_mask);
283-
sigaction(SIGUSR1, &act, &oldact_usr1);
270+
struct timeval tv;
271+
fd_set rfds;
272+
int ret;
284273

285-
/*
286-
* set sigaction for USR2 before fork
287-
* save old sigaction to restore it after
288-
* fork in the child process (the master process)
289-
*/
290-
memset(&act, 0, sizeof(act));
291-
memset(&act, 0, sizeof(oldact_usr2));
292-
act.sa_handler = fpm_signals_sighandler_exit_config;
293-
sigfillset(&act.sa_mask);
294-
sigaction(SIGUSR2, &act, &oldact_usr2);
274+
if (pipe(fpm_globals.send_config_pipe) == -1) {
275+
zlog(ZLOG_SYSERROR, "failed to create pipe");
276+
return -1;
277+
}
295278

296279
/* then fork */
297280
pid_t pid = fork();
@@ -302,24 +285,54 @@ int fpm_unix_init_main() /* {{{ */
302285
return -1;
303286

304287
case 0 : /* children */
305-
/* restore USR1 and USR2 sigaction */
306-
sigaction(SIGUSR1, &oldact_usr1, NULL);
307-
sigaction(SIGUSR2, &oldact_usr2, NULL);
308-
fpm_globals.send_config_signal = 1;
288+
close(fpm_globals.send_config_pipe[0]); /* close the read side of the pipe */
309289
break;
310290

311291
default : /* parent */
312-
fpm_cleanups_run(FPM_CLEANUP_PARENT_EXIT);
292+
close(fpm_globals.send_config_pipe[1]); /* close the write side of the pipe */
313293

314294
/*
315295
* wait for 10s before exiting with error
316-
* the child is supposed to send USR1 or USR2 to tell the parent
296+
* the child is supposed to send 1 or 0 into the pipe to tell the parent
317297
* how it goes for it
318298
*/
299+
FD_ZERO(&rfds);
300+
FD_SET(fpm_globals.send_config_pipe[0], &rfds);
301+
319302
tv.tv_sec = 10;
320303
tv.tv_usec = 0;
321-
zlog(ZLOG_DEBUG, "The calling process is waiting for the master process to ping");
322-
select(0, NULL, NULL, NULL, &tv);
304+
305+
zlog(ZLOG_DEBUG, "The calling process is waiting for the master process to ping via fd=%d", fpm_globals.send_config_pipe[0]);
306+
ret = select(fpm_globals.send_config_pipe[0] + 1, &rfds, NULL, NULL, &tv);
307+
if (ret == -1) {
308+
zlog(ZLOG_SYSERROR, "failed to select");
309+
exit(FPM_EXIT_SOFTWARE);
310+
}
311+
if (ret) { /* data available */
312+
int readval;
313+
ret = read(fpm_globals.send_config_pipe[0], &readval, sizeof(readval));
314+
if (ret == -1) {
315+
zlog(ZLOG_SYSERROR, "failed to read from pipe");
316+
exit(FPM_EXIT_SOFTWARE);
317+
}
318+
319+
if (ret == 0) {
320+
zlog(ZLOG_ERROR, "no data have been read from pipe");
321+
exit(FPM_EXIT_SOFTWARE);
322+
} else {
323+
if (readval == 1) {
324+
zlog(ZLOG_DEBUG, "I received a valid acknoledge from the master process, I can exit without error");
325+
fpm_cleanups_run(FPM_CLEANUP_PARENT_EXIT);
326+
exit(FPM_EXIT_OK);
327+
} else {
328+
zlog(ZLOG_DEBUG, "The master process returned an error !");
329+
exit(FPM_EXIT_SOFTWARE);
330+
}
331+
}
332+
} else { /* no date sent ! */
333+
zlog(ZLOG_ERROR, "the master process didn't send back its status (via the pipe to the calling process)");
334+
exit(FPM_EXIT_SOFTWARE);
335+
}
323336
exit(FPM_EXIT_SOFTWARE);
324337
}
325338
}

0 commit comments

Comments
 (0)