1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2026-06-16 00:25:48 +02:00

Add systemd notify integration.

Allow systemd to have a better understanding as to when pgBackRest has finished starting or is stopping.

This implementation is based off of the existing implementations in
PostgreSQL [1] and PgBouncer [2]. PgBouncer also has an
implementation for `notify-reload` but this is not implemented here
as it is a very recent feature [3] that is unavailable on many Linux
distributions.

[1] https://www.postgresql.org/message-id/flat/CAFj8pRA4%3DhVj-d%3D8O7PSMjopsFUHPcAftd5tLqFC_xb035hNQA%40mail.gmail.com#e346a6189d8b0ed44c745c4aaaef587f
[2] https://github.com/pgbouncer/pgbouncer/commit/3816a0073f09944a6f7eaa278d2226ca4942b911
[3] https://github.com/systemd/systemd/blob/fa6d3bffe30064c4d4092b3daa749465f08d35fb/NEWS#L6176
This commit is contained in:
Andrew Jackson
2026-05-18 21:37:48 -05:00
committed by GitHub
parent 3a6c67183c
commit 742fff174a
12 changed files with 136 additions and 3 deletions
+12
View File
@@ -39,6 +39,18 @@
<p>Improve seek performance during block incremental delta restore.</p>
</release-item>
<release-item>
<github-issue id="2757"/>
<github-pull-request id="2760"/>
<release-item-contributor-list>
<release-item-contributor id="andrew.jackson"/>
<release-item-reviewer id="david.steele"/>
</release-item-contributor-list>
<p>Add <proper>systemd</proper> notify integration.</p>
</release-item>
<release-item>
<github-issue id="2724"/>
+5
View File
@@ -80,6 +80,11 @@
<contributor-id type="github">anarazel</contributor-id>
</contributor>
<contributor id="andrew.jackson">
<contributor-name-display>Andrew Jackson</contributor-name-display>
<contributor-id type="github">AndrewJackson2020</contributor-id>
</contributor>
<contributor id="andrew.lecuyer">
<contributor-name-display>Andrew L'Ecuyer</contributor-name-display>
<contributor-id type="github">andrewlecuyer</contributor-id>
+3 -1
View File
@@ -465,7 +465,7 @@
echo 'StartLimitIntervalSec=0' | tee -a /etc/systemd/system/pgbackrest.service &amp;&amp;
echo '' | tee -a /etc/systemd/system/pgbackrest.service &amp;&amp;
echo '[Service]' | tee -a /etc/systemd/system/pgbackrest.service &amp;&amp;
echo 'Type=simple' | tee -a /etc/systemd/system/pgbackrest.service &amp;&amp;
echo 'Type=notify' | tee -a /etc/systemd/system/pgbackrest.service &amp;&amp;
echo 'Restart=always' | tee -a /etc/systemd/system/pgbackrest.service &amp;&amp;
echo 'RestartSec=1' | tee -a /etc/systemd/system/pgbackrest.service &amp;&amp;
echo 'User={[setup-tls-user]}' | tee -a /etc/systemd/system/pgbackrest.service &amp;&amp;
@@ -1011,6 +1011,7 @@
<exe-cmd>
apt-get install python3-distutils meson gcc libpq-dev libssl-dev libxml2-dev
pkg-config liblz4-dev libzstd-dev libbz2-dev libz-dev libyaml-dev libssh2-1-dev
libsystemd-dev
</exe-cmd>
<exe-cmd-extra>-y 2>&amp;1</exe-cmd-extra>
</execute>
@@ -1019,6 +1020,7 @@
<exe-cmd>
yum install meson gcc postgresql{[pg-version]}-devel openssl-devel
libxml2-devel lz4-devel libzstd-devel bzip2-devel libyaml-devel libssh2-devel
systemd-devel
</exe-cmd>
<exe-cmd-extra>-y 2>&amp;1</exe-cmd-extra>
</execute>
+7
View File
@@ -211,6 +211,13 @@ lib_z = dependency('zlib')
configuration.set('ZLIB_CONST', true, description: 'Require zlib const input buffer')
# Find optional systemd library
lib_systemd = dependency('libsystemd', required: get_option('libsystemd'))
if lib_systemd.found()
configuration.set('HAVE_LIBSYSTEMD', true, description: 'Is libsystemd present?')
endif
# Find optional libssh2 library
lib_ssh2 = dependency('libssh2', required: get_option('libssh2'))
+1
View File
@@ -2,3 +2,4 @@ option('configdir', type: 'string', value: '/etc/pgbackrest', description: 'Conf
option('fatal-errors', type: 'boolean', value: false, description: 'Stop compilation on first error')
option('libssh2', type: 'feature', value: 'auto', description: 'Enable SFTP storage support')
option('libzstd', type: 'feature', value: 'auto', description: 'Enable Zstandard compression support')
option('libsystemd', type: 'feature', value: 'auto', description: 'Enable systemd notify support')
+13
View File
@@ -4,6 +4,9 @@ Server Command
#include <build.h>
#include <sys/wait.h>
#ifdef HAVE_LIBSYSTEMD
#include <systemd/sd-daemon.h>
#endif
#include "command/exit.h"
#include "command/remote/remote.h"
@@ -134,6 +137,11 @@ cmdServer(const unsigned int argListSize, const char *argList[])
SIGCHLD, &(struct sigaction){.sa_sigaction = cmdServerSigChild, .sa_flags = SA_NOCLDSTOP | SA_NOCLDWAIT | SA_SIGINFO},
NULL);
// Notify systemd that we are ready to accept connections
#ifdef HAVE_LIBSYSTEMD
sd_notify(0, "READY=1");
#endif
// Accept connections indefinitely. The only way to exit this loop is for the process to receive a signal.
do
{
@@ -196,6 +204,11 @@ cmdServer(const unsigned int argListSize, const char *argList[])
}
MEM_CONTEXT_TEMP_END();
// Notify systemd that we are shutting down
#ifdef HAVE_LIBSYSTEMD
sd_notify(0, "STOPPING=1");
#endif
// Terminate any remaining children on SIGTERM. Disable the callback so it does not fire in the middle of the loop.
if (serverLocal.sigTerm)
{
+1
View File
@@ -282,6 +282,7 @@ executable(
lib_bz2,
lib_openssl,
lib_lz4,
lib_systemd,
lib_pq,
lib_ssh2,
lib_xml,
+1
View File
@@ -1028,6 +1028,7 @@ unit:
# ----------------------------------------------------------------------------------------------------------------------------
- name: server
total: 2
harness: systemd
coverage:
- command/server/ping
@@ -402,7 +402,7 @@ sub containerBuild
" perl perl-Digest-SHA perl-DBD-Pg perl-YAML-LibYAML openssl \\\n" .
" gcc make perl-ExtUtils-MakeMaker perl-Test-Simple openssl-devel perl-ExtUtils-Embed rpm-build \\\n" .
" libyaml-devel zlib-devel libxml2-devel lz4-devel lz4 bzip2-devel bzip2 perl-JSON-PP ccache meson \\\n" .
" libssh2-devel zstd libzstd-devel";
" libssh2-devel zstd libzstd-devel systemd-devel";
}
elsif ($$oVm{$strOS}{&VM_OS_BASE} eq VM_OS_BASE_DEBIAN)
{
@@ -414,7 +414,7 @@ sub containerBuild
" libyaml-libyaml-perl tzdata devscripts lintian libxml-checker-perl txt2man debhelper \\\n" .
" libppi-html-perl libtemplate-perl libtest-differences-perl zlib1g-dev libxml2-dev pkg-config \\\n" .
" libbz2-dev bzip2 libyaml-dev libjson-pp-perl liblz4-dev liblz4-tool gnupg lsb-release ccache meson \\\n" .
" libssh2-1-dev libcurl4-openssl-dev";
" libssh2-1-dev libcurl4-openssl-dev libsystemd-dev";
if ($strOS eq VM_U22)
{
+63
View File
@@ -0,0 +1,63 @@
/***********************************************************************************************************************************
Systemd Harness
***********************************************************************************************************************************/
#include <build.h>
#include <string.h>
#include "common/debug.h"
#include "common/log.h"
#include "common/harnessDebug.h"
#include "common/harnessSystemd.h"
static struct
{
bool ready;
bool stopping;
} hrnSystemdStatic;
/***********************************************************************************************************************************
Shim sd_notify to track notify state
***********************************************************************************************************************************/
#ifdef HAVE_LIBSYSTEMD
int
sd_notify(int unset_environment, const char *state)
{
FUNCTION_HARNESS_BEGIN();
FUNCTION_HARNESS_PARAM(INT, unset_environment);
FUNCTION_HARNESS_PARAM(STRINGZ, state);
FUNCTION_HARNESS_END();
ASSERT(unset_environment == 0);
ASSERT(state != NULL);
if (strcmp(state, "READY=1") == 0)
{
ASSERT(!hrnSystemdStatic.stopping);
hrnSystemdStatic.ready = true;
}
else if (strcmp(state, "STOPPING=1") == 0)
{
ASSERT(hrnSystemdStatic.ready);
hrnSystemdStatic.stopping = true;
}
else
THROW_FMT(AssertError, "unknown sd_notify state '%s'", state);
FUNCTION_HARNESS_RETURN(INT, 1);
}
#endif
/**********************************************************************************************************************************/
void
hrnSystemDCheck(void)
{
FUNCTION_HARNESS_VOID();
ASSERT(hrnSystemdStatic.ready && hrnSystemdStatic.stopping);
FUNCTION_HARNESS_RETURN_VOID();
}
+17
View File
@@ -0,0 +1,17 @@
/***********************************************************************************************************************************
Systemd Harness
***********************************************************************************************************************************/
#ifndef TEST_COMMON_HARNESS_SYSTEMD_H
#define TEST_COMMON_HARNESS_SYSTEMD_H
#ifdef HAVE_LIBSYSTEMD
#include <systemd/sd-daemon.h>
#endif
/***********************************************************************************************************************************
Functions
***********************************************************************************************************************************/
// Check that sd_notify calls were made
void hrnSystemDCheck(void);
#endif
+11
View File
@@ -9,6 +9,7 @@ Test Server Command
#include "common/harnessFork.h"
#include "common/harnessServer.h"
#include "common/harnessStorage.h"
#include "common/harnessSystemd.h"
/***********************************************************************************************************************************
Test Run
@@ -168,6 +169,11 @@ testRun(void)
HRN_FORK_CHILD_NOTIFY_PUT();
exit(0);
}
// Check that sd_notify calls were made
#ifdef HAVE_LIBSYSTEMD
hrnSystemDCheck();
#endif
}
HRN_FORK_CHILD_END();
@@ -273,6 +279,11 @@ testRun(void)
HRN_FORK_CHILD_NOTIFY_PUT();
exit(0);
}
// Check that sd_notify calls were made
#ifdef HAVE_LIBSYSTEMD
hrnSystemDCheck();
#endif
}
HRN_FORK_CHILD_END();