Le 17/05/2013 18:44, Remi Collet a écrit : > Any feedback before I process ?
>From proposal from Jérôme, I have add a new "systemd_interval" option to configure the interval between 2 systemd notification (0 means disabled, except initial notification which stay mandatory by design) Note : this small feature also allow to set the service in watchdog mode (it will enter "failed" state if systemd don't receive notification during configured interval). In this case, the watchdog interval overrides the configured interval option. Remi.
diff -up ../sapi/fpm/config.m4.systemd ../sapi/fpm/config.m4 --- ../sapi/fpm/config.m4.systemd 2012-12-05 11:40:54.000000000 +0100 +++ ../sapi/fpm/config.m4 2013-05-18 16:24:20.016490912 +0200 @@ -563,6 +563,26 @@ if test "$PHP_FPM" != "no"; then [ --with-fpm-group[=GRP] Set the group for php-fpm to run as. For a system user, this should usually be set to match the fpm username (default: nobody)], nobody, no) + PHP_ARG_WITH(fpm-systemd,, + [ --with-fpm-systemd Activate systemd integration], no, no) + + if test "$PHP_FPM_SYSTEMD" != "no" ; then + AC_CHECK_LIB(systemd-daemon, sd_notify, SYSTEMD_LIBS="-lsystemd-daemon") + AC_CHECK_HEADERS(systemd/sd-daemon.h, [HAVE_SD_DAEMON_H="yes"], [HAVE_SD_DAEMON_H="no"]) + if test $HAVE_SD_DAEMON_H = "no" || test -z "${SYSTEMD_LIBS}"; then + AC_MSG_ERROR([Your system does not support systemd.]) + else + AC_DEFINE(HAVE_SYSTEMD, 1, [FPM use systemd integration]) + PHP_FPM_SD_FILES="fpm/fpm_systemd.c" + PHP_ADD_LIBRARY(systemd-daemon) + php_fpm_systemd=notify + fi + else + php_fpm_systemd=simple + fi + PHP_SUBST_OLD(php_fpm_systemd) + AC_DEFINE_UNQUOTED(PHP_FPM_SYSTEMD, "$php_fpm_systemd", [fpm systemd service type]) + if test -z "$PHP_FPM_USER" -o "$PHP_FPM_USER" = "yes" -o "$PHP_FPM_USER" = "no"; then php_fpm_user="nobody" else @@ -631,7 +651,7 @@ if test "$PHP_FPM" != "no"; then fpm/events/port.c \ " - PHP_SELECT_SAPI(fpm, program, $PHP_FPM_FILES $PHP_FPM_TRACE_FILES, $PHP_FPM_CFLAGS, '$(SAPI_FPM_PATH)') + PHP_SELECT_SAPI(fpm, program, $PHP_FPM_FILES $PHP_FPM_TRACE_FILES $PHP_FPM_SD_FILES, $PHP_FPM_CFLAGS, '$(SAPI_FPM_PATH)') case $host_alias in *aix*) diff -up ../sapi/fpm/fpm/fpm_conf.c.systemd ../sapi/fpm/fpm/fpm_conf.c --- ../sapi/fpm/fpm/fpm_conf.c.systemd 2013-05-18 16:59:35.036005958 +0200 +++ ../sapi/fpm/fpm/fpm_conf.c 2013-05-18 17:21:16.990441007 +0200 @@ -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_co #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 { "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 } }; @@ -1152,6 +1163,12 @@ static int fpm_conf_post_process(int for 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"); diff -up ../sapi/fpm/fpm/fpm_conf.h.systemd ../sapi/fpm/fpm/fpm_conf.h --- ../sapi/fpm/fpm/fpm_conf.h.systemd 2013-05-18 16:59:30.622990279 +0200 +++ ../sapi/fpm/fpm/fpm_conf.h 2013-05-18 17:00:48.777267967 +0200 @@ -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; diff -up ../sapi/fpm/fpm/fpm_events.c.systemd ../sapi/fpm/fpm/fpm_events.c --- ../sapi/fpm/fpm/fpm_events.c.systemd 2012-12-05 11:40:39.000000000 +0100 +++ ../sapi/fpm/fpm/fpm_events.c 2013-05-18 16:24:20.016490912 +0200 @@ -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 -up ../sapi/fpm/fpm/fpm_systemd.c.systemd ../sapi/fpm/fpm/fpm_systemd.c --- ../sapi/fpm/fpm/fpm_systemd.c.systemd 2013-05-18 16:24:20.017490915 +0200 +++ ../sapi/fpm/fpm/fpm_systemd.c 2013-05-18 17:53:48.109578519 +0200 @@ -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 -up ../sapi/fpm/fpm/fpm_systemd.h.systemd ../sapi/fpm/fpm/fpm_systemd.h --- ../sapi/fpm/fpm/fpm_systemd.h.systemd 2013-05-18 16:24:20.017490915 +0200 +++ ../sapi/fpm/fpm/fpm_systemd.h 2013-05-18 17:13:54.278830609 +0200 @@ -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 + diff -up ../sapi/fpm/php-fpm.service.in.systemd ../sapi/fpm/php-fpm.service.in --- ../sapi/fpm/php-fpm.service.in.systemd 2012-12-05 11:40:39.000000000 +0100 +++ ../sapi/fpm/php-fpm.service.in 2013-05-18 16:24:20.017490915 +0200 @@ -3,6 +3,7 @@ Description=The PHP FastCGI Process Mana After=syslog.target network.target [Service] +Type=@php_fpm_systemd@ PIDFile=@localstatedir@/run/php-fpm.pid ExecStart=@sbindir@/php-fpm --nodaemonize --fpm-config @sysconfdir@/php-fpm.conf ExecReload=/bin/kill -USR2 $MAINPID
-- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php