Skip to content

Commit c79f162

Browse files
committed
Merge branch 'PHP-5.4' into PHP-5.5
* PHP-5.4: Add --with-fpm-systemd option to report health to systemd, and systemd_interval option to configure this. The service can now use Type=notify in the systemd unit file.
2 parents a2d6d27 + 0e99329 commit c79f162

8 files changed

Lines changed: 189 additions & 2 deletions

File tree

sapi/fpm/config.m4

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -563,6 +563,26 @@ if test "$PHP_FPM" != "no"; then
563563
[ --with-fpm-group[=GRP] Set the group for php-fpm to run as. For a system user, this
564564
should usually be set to match the fpm username (default: nobody)], nobody, no)
565565

566+
PHP_ARG_WITH(fpm-systemd,,
567+
[ --with-fpm-systemd Activate systemd integration], no, no)
568+
569+
if test "$PHP_FPM_SYSTEMD" != "no" ; then
570+
AC_CHECK_LIB(systemd-daemon, sd_notify, SYSTEMD_LIBS="-lsystemd-daemon")
571+
AC_CHECK_HEADERS(systemd/sd-daemon.h, [HAVE_SD_DAEMON_H="yes"], [HAVE_SD_DAEMON_H="no"])
572+
if test $HAVE_SD_DAEMON_H = "no" || test -z "${SYSTEMD_LIBS}"; then
573+
AC_MSG_ERROR([Your system does not support systemd.])
574+
else
575+
AC_DEFINE(HAVE_SYSTEMD, 1, [FPM use systemd integration])
576+
PHP_FPM_SD_FILES="fpm/fpm_systemd.c"
577+
PHP_ADD_LIBRARY(systemd-daemon)
578+
php_fpm_systemd=notify
579+
fi
580+
else
581+
php_fpm_systemd=simple
582+
fi
583+
PHP_SUBST_OLD(php_fpm_systemd)
584+
AC_DEFINE_UNQUOTED(PHP_FPM_SYSTEMD, "$php_fpm_systemd", [fpm systemd service type])
585+
566586
if test -z "$PHP_FPM_USER" -o "$PHP_FPM_USER" = "yes" -o "$PHP_FPM_USER" = "no"; then
567587
php_fpm_user="nobody"
568588
else
@@ -631,7 +651,7 @@ if test "$PHP_FPM" != "no"; then
631651
fpm/events/port.c \
632652
"
633653

634-
PHP_SELECT_SAPI(fpm, program, $PHP_FPM_FILES $PHP_FPM_TRACE_FILES, $PHP_FPM_CFLAGS, '$(SAPI_FPM_PATH)')
654+
PHP_SELECT_SAPI(fpm, program, $PHP_FPM_FILES $PHP_FPM_TRACE_FILES $PHP_FPM_SD_FILES, $PHP_FPM_CFLAGS, '$(SAPI_FPM_PATH)')
635655

636656
case $host_alias in
637657
*aix*)

sapi/fpm/fpm/fpm_conf.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@
4545
#include "fpm_log.h"
4646
#include "fpm_events.h"
4747
#include "zlog.h"
48+
#ifdef HAVE_SYSTEMD
49+
#include "fpm_systemd.h"
50+
#endif
51+
4852

4953
#define STR2STR(a) (a ? a : "undefined")
5054
#define BOOL2STR(a) (a ? "yes" : "no")
@@ -73,6 +77,10 @@ struct fpm_global_config_s fpm_global_config = {
7377
#endif
7478
.process_max = 0,
7579
.process_priority = 64, /* 64 means unset */
80+
#ifdef HAVE_SYSTEMD
81+
.systemd_watchdog = 0,
82+
.systemd_interval = -1, /* -1 means not set */
83+
#endif
7684
};
7785
static struct fpm_worker_pool_s *current_wp = NULL;
7886
static int ini_recursion = 0;
@@ -100,6 +108,9 @@ static struct ini_value_parser_s ini_fpm_global_options[] = {
100108
{ "rlimit_files", &fpm_conf_set_integer, GO(rlimit_files) },
101109
{ "rlimit_core", &fpm_conf_set_rlimit_core, GO(rlimit_core) },
102110
{ "events.mechanism", &fpm_conf_set_string, GO(events_mechanism) },
111+
#ifdef HAVE_SYSTEMD
112+
{ "systemd_interval", &fpm_conf_set_time, GO(systemd_interval) },
113+
#endif
103114
{ 0, 0, 0 }
104115
};
105116

@@ -1152,6 +1163,12 @@ static int fpm_conf_post_process(int force_daemon TSRMLS_DC) /* {{{ */
11521163
fpm_global_config.error_log = strdup("log/php-fpm.log");
11531164
}
11541165

1166+
#ifdef HAVE_SYSTEMD
1167+
if (0 > fpm_systemd_conf()) {
1168+
return -1;
1169+
}
1170+
#endif
1171+
11551172
#ifdef HAVE_SYSLOG_H
11561173
if (!fpm_global_config.syslog_ident) {
11571174
fpm_global_config.syslog_ident = strdup("php-fpm");
@@ -1540,6 +1557,9 @@ static void fpm_conf_dump() /* {{{ */
15401557
zlog(ZLOG_NOTICE, "\trlimit_files = %d", fpm_global_config.rlimit_files);
15411558
zlog(ZLOG_NOTICE, "\trlimit_core = %d", fpm_global_config.rlimit_core);
15421559
zlog(ZLOG_NOTICE, "\tevents.mechanism = %s", fpm_event_machanism_name());
1560+
#ifdef HAVE_SYSTEMD
1561+
zlog(ZLOG_NOTICE, "\tsystemd_interval = %ds", fpm_global_config.systemd_interval/1000);
1562+
#endif
15431563
zlog(ZLOG_NOTICE, " ");
15441564

15451565
for (wp = fpm_worker_all_pools; wp; wp = wp->next) {

sapi/fpm/fpm/fpm_conf.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ struct fpm_global_config_s {
4040
int rlimit_files;
4141
int rlimit_core;
4242
char *events_mechanism;
43+
#ifdef HAVE_SYSTEMD
44+
int systemd_watchdog;
45+
int systemd_interval;
46+
#endif
4347
};
4448

4549
extern struct fpm_global_config_s fpm_global_config;

sapi/fpm/fpm/fpm_events.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@
2929
#include "events/port.h"
3030
#include "events/kqueue.h"
3131

32+
#ifdef HAVE_SYSTEMD
33+
#include "fpm_systemd.h"
34+
#endif
35+
3236
#define fpm_event_set_timeout(ev, now) timeradd(&(now), &(ev)->frequency, &(ev)->timeout);
3337

3438
static void fpm_event_cleanup(int which, void *arg);
@@ -361,6 +365,10 @@ void fpm_event_loop(int err) /* {{{ */
361365

362366
zlog(ZLOG_DEBUG, "%zu bytes have been reserved in SHM", fpm_shm_get_size_allocated());
363367
zlog(ZLOG_NOTICE, "ready to handle connections");
368+
369+
#ifdef HAVE_SYSTEMD
370+
fpm_systemd_heartbeat(NULL, 0, NULL);
371+
#endif
364372
}
365373

366374
while (1) {

sapi/fpm/fpm/fpm_systemd.c

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
#include "fpm_config.h"
2+
3+
#include <sys/types.h>
4+
#include <systemd/sd-daemon.h>
5+
6+
#include "fpm.h"
7+
#include "fpm_clock.h"
8+
#include "fpm_worker_pool.h"
9+
#include "fpm_scoreboard.h"
10+
#include "zlog.h"
11+
#include "fpm_systemd.h"
12+
13+
14+
static void fpm_systemd() /* {{{ */
15+
{
16+
static unsigned long int last=0;
17+
struct fpm_worker_pool_s *wp;
18+
unsigned long int requests=0, slow_req=0;
19+
int active=0, idle=0;
20+
21+
22+
for (wp = fpm_worker_all_pools; wp; wp = wp->next) {
23+
if (wp->scoreboard) {
24+
active += wp->scoreboard->active;
25+
idle += wp->scoreboard->idle;
26+
requests += wp->scoreboard->requests;
27+
slow_req += wp->scoreboard->slow_rq;
28+
}
29+
}
30+
31+
/*
32+
zlog(ZLOG_DEBUG, "systemd %s (Processes active:%d, idle:%d, Requests:%lu, slow:%lu, Traffic:%.3greq/sec)",
33+
fpm_global_config.systemd_watchdog ? "watchdog" : "heartbeat",
34+
active, idle, requests, slow_req, ((float)requests - last) * 1000.0 / fpm_global_config.systemd_interval);
35+
*/
36+
37+
if (0 > sd_notifyf(0, "READY=1\n%s"
38+
"STATUS=Processes active: %d, idle: %d, Requests: %lu, slow: %lu, Traffic: %.3greq/sec",
39+
fpm_global_config.systemd_watchdog ? "WATCHDOG=1\n" : "",
40+
active, idle, requests, slow_req, ((float)requests - last) * 1000.0 / fpm_global_config.systemd_interval)) {
41+
zlog(ZLOG_NOTICE, "failed to notify status to systemd");
42+
}
43+
44+
last = requests;
45+
}
46+
/* }}} */
47+
48+
void fpm_systemd_heartbeat(struct fpm_event_s *ev, short which, void *arg) /* {{{ */
49+
{
50+
static struct fpm_event_s heartbeat;
51+
52+
if (fpm_globals.parent_pid != getpid()) {
53+
return; /* sanity check */
54+
}
55+
56+
if (which == FPM_EV_TIMEOUT) {
57+
fpm_systemd();
58+
59+
return;
60+
}
61+
62+
if (0 > sd_notifyf(0, "READY=1\n"
63+
"STATUS=Ready to handle connections\n"
64+
"MAINPID=%lu",
65+
(unsigned long) getpid())) {
66+
zlog(ZLOG_WARNING, "failed to notify start to systemd");
67+
} else {
68+
zlog(ZLOG_DEBUG, "have notify start to systemd");
69+
}
70+
71+
/* first call without setting which to initialize the timer */
72+
if (fpm_global_config.systemd_interval > 0) {
73+
fpm_event_set_timer(&heartbeat, FPM_EV_PERSIST, &fpm_systemd_heartbeat, NULL);
74+
fpm_event_add(&heartbeat, fpm_global_config.systemd_interval);
75+
zlog(ZLOG_NOTICE, "systemd monitor interval set to %dms", fpm_global_config.systemd_interval);
76+
} else {
77+
zlog(ZLOG_NOTICE, "systemd monitor disabled");
78+
}
79+
}
80+
/* }}} */
81+
82+
int fpm_systemd_conf() /* {{{ */
83+
{
84+
char *watchdog;
85+
int interval = 0;
86+
87+
watchdog = getenv("WATCHDOG_USEC");
88+
if (watchdog) {
89+
/* usec to msec, and half the configured delay */
90+
interval = (int)(atol(watchdog) / 2000L);
91+
zlog(ZLOG_DEBUG, "WATCHDOG_USEC=%s, interval=%d", watchdog, interval);
92+
}
93+
94+
if (interval > 1000) {
95+
if (fpm_global_config.systemd_interval > 0) {
96+
zlog(ZLOG_WARNING, "systemd_interval option ignored");
97+
}
98+
zlog(ZLOG_NOTICE, "systemd watchdog configured to %.3gsec", (float)interval / 1000.0);
99+
fpm_global_config.systemd_watchdog = 1;
100+
fpm_global_config.systemd_interval = interval;
101+
102+
} else if (fpm_global_config.systemd_interval < 0) {
103+
/* not set => default value */
104+
fpm_global_config.systemd_interval = FPM_SYSTEMD_DEFAULT_HEARTBEAT;
105+
106+
} else {
107+
/* sec to msec */
108+
fpm_global_config.systemd_interval *= 1000;
109+
}
110+
return 0;
111+
}
112+
/* }}} */
113+

sapi/fpm/fpm/fpm_systemd.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#ifndef FPM_SYSTEMD_H
2+
#define FPM_SYSTEMD_H 1
3+
4+
#include "fpm_events.h"
5+
6+
/* 10s (in ms) heartbeat for systemd status */
7+
#define FPM_SYSTEMD_DEFAULT_HEARTBEAT (10000)
8+
9+
void fpm_systemd_heartbeat(struct fpm_event_s *ev, short which, void *arg);
10+
int fpm_systemd_conf();
11+
12+
#endif
13+

sapi/fpm/php-fpm.conf.in

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,15 @@
105105
; - /dev/poll (Solaris >= 7)
106106
; - port (Solaris >= 10)
107107
; Default Value: not set (auto detection)
108-
; events.mechanism = epoll
108+
;events.mechanism = epoll
109+
110+
; When FPM is build with systemd integration, specify the interval,
111+
; in second, between health report notification to systemd.
112+
; Set to 0 to disable.
113+
; Available Units: s(econds), m(inutes), h(ours)
114+
; Default Unit: seconds
115+
; Default value: 10
116+
;systemd_interval = 10
109117

110118
;;;;;;;;;;;;;;;;;;;;
111119
; Pool Definitions ;

sapi/fpm/php-fpm.service.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ Description=The PHP FastCGI Process Manager
33
After=syslog.target network.target
44

55
[Service]
6+
Type=@php_fpm_systemd@
67
PIDFile=@localstatedir@/run/php-fpm.pid
78
ExecStart=@sbindir@/php-fpm --nodaemonize --fpm-config @sysconfdir@/php-fpm.conf
89
ExecReload=/bin/kill -USR2 $MAINPID

0 commit comments

Comments
 (0)