From 7d17e683fcc28a1b371c7dd02935728cd2cbf9bf Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Tue, 17 Nov 2015 06:46:17 -0500 Subject: [PATCH] Add support for systemd service notifications MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Insert sd_notify() calls at server start and stop for integration with systemd. This allows the use of systemd service units of type "notify", which greatly simplifies the systemd configuration. Reviewed-by: Pavel Stěhule --- configure | 49 +++++++++++++++++++++++++++++ configure.in | 13 ++++++++ doc/src/sgml/installation.sgml | 16 ++++++++++ doc/src/sgml/runtime.sgml | 35 +++++++++++++++++++++ src/Makefile.global.in | 1 + src/backend/Makefile | 4 +++ src/backend/postmaster/postmaster.c | 26 +++++++++++++++ src/include/pg_config.h.in | 3 ++ 8 files changed, 147 insertions(+) diff --git a/configure b/configure index 3dd1b152c6..b3f3abe2e1 100755 --- a/configure +++ b/configure @@ -709,6 +709,7 @@ with_libxml XML2_CONFIG UUID_EXTRA_OBJS with_uuid +with_systemd with_selinux with_openssl krb_srvtab @@ -830,6 +831,7 @@ with_ldap with_bonjour with_openssl with_selinux +with_systemd with_readline with_libedit_preferred with_uuid @@ -1518,6 +1520,7 @@ Optional Packages: --with-bonjour build with Bonjour support --with-openssl build with OpenSSL support --with-selinux build with SELinux support + --with-systemd build with systemd support --without-readline do not use GNU Readline nor BSD Libedit for editing --with-libedit-preferred prefer BSD Libedit over GNU Readline @@ -5694,6 +5697,41 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_selinux" >&5 $as_echo "$with_selinux" >&6; } +# +# Systemd +# +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build with systemd support" >&5 +$as_echo_n "checking whether to build with systemd support... " >&6; } + + + +# Check whether --with-systemd was given. +if test "${with_systemd+set}" = set; then : + withval=$with_systemd; + case $withval in + yes) + +$as_echo "#define USE_SYSTEMD 1" >>confdefs.h + + ;; + no) + : + ;; + *) + as_fn_error $? "no argument expected for --with-systemd option" "$LINENO" 5 + ;; + esac + +else + with_systemd=no + +fi + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_systemd" >&5 +$as_echo "$with_systemd" >&6; } + # # Readline # @@ -10473,6 +10511,17 @@ fi done +fi + +if test "$with_systemd" = yes ; then + ac_fn_c_check_header_mongrel "$LINENO" "systemd/sd-daemon.h" "ac_cv_header_systemd_sd_daemon_h" "$ac_includes_default" +if test "x$ac_cv_header_systemd_sd_daemon_h" = xyes; then : + +else + as_fn_error $? "header file is required for systemd support" "$LINENO" 5 +fi + + fi if test "$with_libxml" = yes ; then diff --git a/configure.in b/configure.in index 93984822e4..0bd90d7501 100644 --- a/configure.in +++ b/configure.in @@ -699,6 +699,15 @@ PGAC_ARG_BOOL(with, selinux, no, [build with SELinux support]) AC_SUBST(with_selinux) AC_MSG_RESULT([$with_selinux]) +# +# Systemd +# +AC_MSG_CHECKING([whether to build with systemd support]) +PGAC_ARG_BOOL(with, systemd, no, [build with systemd support], + [AC_DEFINE([USE_SYSTEMD], 1, [Define to build with systemd support. (--with-systemd)])]) +AC_SUBST(with_systemd) +AC_MSG_RESULT([$with_systemd]) + # # Readline # @@ -1249,6 +1258,10 @@ if test "$with_pam" = yes ; then [AC_MSG_ERROR([header file or is required for PAM.])])]) fi +if test "$with_systemd" = yes ; then + AC_CHECK_HEADER(systemd/sd-daemon.h, [], [AC_MSG_ERROR([header file is required for systemd support])]) +fi + if test "$with_libxml" = yes ; then AC_CHECK_HEADER(libxml/parser.h, [], [AC_MSG_ERROR([header file is required for XML support])]) fi diff --git a/doc/src/sgml/installation.sgml b/doc/src/sgml/installation.sgml index 8dcedc0aaa..00686a73ca 100644 --- a/doc/src/sgml/installation.sgml +++ b/doc/src/sgml/installation.sgml @@ -812,6 +812,22 @@ su - postgres + + + + + Build with support + for systemdsystemd + service notifications. This improves integration if the server binary + is started under systemd but has no impact + otherwise; see for more + information. libsystemd and the + associated header files need to be installed to be able to use this + option. + + + + diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index cda05f578a..209eb9e523 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -369,6 +369,41 @@ fi contrib/start-scripts/linux in the PostgreSQL source distribution. + + + When using systemd, you can use the following + service unit file (e.g., + at /etc/systemd/system/postgresql.service):systemd + +[Unit] +Description=PostgreSQL database server +Documentation=man:postgres(1) + +[Service] +Type=notify +User=postgres +ExecStart=/usr/local/pgsql/bin/postgres -D /usr/local/pgsql/data +ExecReload=/bin/kill -HUP $MAINPID +KillMode=mixed +KillSignal=SIGINT +TimeoutSec=0 + +[Install] +WantedBy=multi-user.target + + Using Type=notify requires that the server binary was + built with configure --with-systemd. + + + + Consider carefully the timeout + setting. systemd has a default timeout of 90 + seconds as of this writing and will kill a process that does not notify + readiness within that time. But a PostgreSQL + server that might have to perform crash recovery at startup could take + much longer to become ready. The suggested value of 0 disables the + timeout logic. + diff --git a/src/Makefile.global.in b/src/Makefile.global.in index 51f479713c..e94d6a58a0 100644 --- a/src/Makefile.global.in +++ b/src/Makefile.global.in @@ -184,6 +184,7 @@ with_python = @with_python@ with_tcl = @with_tcl@ with_openssl = @with_openssl@ with_selinux = @with_selinux@ +with_systemd = @with_systemd@ with_libxml = @with_libxml@ with_libxslt = @with_libxslt@ with_system_tzdata = @with_system_tzdata@ diff --git a/src/backend/Makefile b/src/backend/Makefile index d4db8ff57a..b3d5e2e1bd 100644 --- a/src/backend/Makefile +++ b/src/backend/Makefile @@ -45,6 +45,10 @@ LIBS := $(filter-out -lpgport -lpgcommon, $(LIBS)) $(LDAP_LIBS_BE) # The backend doesn't need everything that's in LIBS, however LIBS := $(filter-out -lz -lreadline -ledit -ltermcap -lncurses -lcurses, $(LIBS)) +ifeq ($(with_systemd),yes) +LIBS += -lsystemd +endif + ########################################################################## all: submake-libpgport submake-schemapg postgres $(POSTGRES_IMP) diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c index 9aaed5b984..d983a50ee1 100644 --- a/src/backend/postmaster/postmaster.c +++ b/src/backend/postmaster/postmaster.c @@ -87,6 +87,10 @@ #include #endif +#ifdef USE_SYSTEMD +#include +#endif + #ifdef HAVE_PTHREAD_IS_THREADED_NP #include #endif @@ -2533,6 +2537,9 @@ pmdie(SIGNAL_ARGS) Shutdown = SmartShutdown; ereport(LOG, (errmsg("received smart shutdown request"))); +#ifdef USE_SYSTEMD + sd_notify(0, "STOPPING=1"); +#endif if (pmState == PM_RUN || pmState == PM_RECOVERY || pmState == PM_HOT_STANDBY || pmState == PM_STARTUP) @@ -2585,6 +2592,9 @@ pmdie(SIGNAL_ARGS) Shutdown = FastShutdown; ereport(LOG, (errmsg("received fast shutdown request"))); +#ifdef USE_SYSTEMD + sd_notify(0, "STOPPING=1"); +#endif if (StartupPID != 0) signal_child(StartupPID, SIGTERM); @@ -2645,6 +2655,9 @@ pmdie(SIGNAL_ARGS) Shutdown = ImmediateShutdown; ereport(LOG, (errmsg("received immediate shutdown request"))); +#ifdef USE_SYSTEMD + sd_notify(0, "STOPPING=1"); +#endif TerminateChildren(SIGQUIT); pmState = PM_WAIT_BACKENDS; @@ -2787,6 +2800,10 @@ reaper(SIGNAL_ARGS) ereport(LOG, (errmsg("database system is ready to accept connections"))); +#ifdef USE_SYSTEMD + sd_notify(0, "READY=1"); +#endif + continue; } @@ -4916,6 +4933,11 @@ sigusr1_handler(SIGNAL_ARGS) if (XLogArchivingAlways()) PgArchPID = pgarch_start(); +#ifdef USE_SYSTEMD + if (!EnableHotStandby) + sd_notify(0, "READY=1"); +#endif + pmState = PM_RECOVERY; } if (CheckPostmasterSignal(PMSIGNAL_BEGIN_HOT_STANDBY) && @@ -4930,6 +4952,10 @@ sigusr1_handler(SIGNAL_ARGS) ereport(LOG, (errmsg("database system is ready to accept read only connections"))); +#ifdef USE_SYSTEMD + sd_notify(0, "READY=1"); +#endif + pmState = PM_HOT_STANDBY; /* Some workers may be scheduled to start now */ StartWorkerNeeded = true; diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in index 16a272efde..b3ceea5edc 100644 --- a/src/include/pg_config.h.in +++ b/src/include/pg_config.h.in @@ -833,6 +833,9 @@ /* Define to 1 to use Intel SSSE 4.2 CRC instructions with a runtime check. */ #undef USE_SSE42_CRC32C_WITH_RUNTIME_CHECK +/* Define to build with systemd support. (--with-systemd) */ +#undef USE_SYSTEMD + /* Define to select SysV-style semaphores. */ #undef USE_SYSV_SEMAPHORES -- 2.40.0