mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-31 06:25:31 +00:00
rem: pkg: Implement the systemd notification protocol manually to remove dependency on libsystemd.
Merge branch 'aydin/standalone-notification' into 'main' See merge request isc-projects/bind9!10263
This commit is contained in:
@@ -13,7 +13,6 @@ AM_CPPFLAGS += \
|
||||
$(MAXMINDDB_CFLAGS) \
|
||||
$(DNSTAP_CFLAGS) \
|
||||
$(LIBUV_CFLAGS) \
|
||||
$(LIBSYSTEMD_CFLAGS) \
|
||||
$(ZLIB_CFLAGS)
|
||||
|
||||
if HAVE_JSON_C
|
||||
@@ -108,7 +107,6 @@ named_LDADD = \
|
||||
$(MAXMINDDB_LIBS) \
|
||||
$(DNSTAP_LIBS) \
|
||||
$(LIBUV_LIBS) \
|
||||
$(LIBSYSTEMD_LIBS) \
|
||||
$(ZLIB_LIBS)
|
||||
|
||||
if HAVE_JSON_C
|
||||
|
@@ -18,6 +18,7 @@
|
||||
#include <pwd.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <isc/formatcheck.h>
|
||||
#include <isc/types.h>
|
||||
|
||||
void
|
||||
@@ -73,3 +74,15 @@ named_os_started(void);
|
||||
|
||||
const char *
|
||||
named_os_uname(void);
|
||||
|
||||
#ifdef __linux__
|
||||
void
|
||||
named_os_notify_systemd(const char *restrict format, ...)
|
||||
ISC_FORMAT_PRINTF(1, 2);
|
||||
|
||||
void
|
||||
named_os_notify_close(void);
|
||||
#else /* __linux__ */
|
||||
#define named_os_notify_systemd(...)
|
||||
#define named_os_notify_close(...)
|
||||
#endif /* __linux__ */
|
||||
|
118
bin/named/os.c
118
bin/named/os.c
@@ -36,6 +36,7 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include <isc/buffer.h>
|
||||
#include <isc/errno.h>
|
||||
#include <isc/file.h>
|
||||
#include <isc/result.h>
|
||||
#include <isc/strerr.h>
|
||||
@@ -60,6 +61,7 @@ static int devnullfd = -1;
|
||||
static struct passwd *runas_pw = NULL;
|
||||
static bool done_setuid = false;
|
||||
static int dfd[2] = { -1, -1 };
|
||||
static int notify_fd = -1;
|
||||
|
||||
static uid_t saved_uid = (uid_t)-1;
|
||||
static gid_t saved_gid = (gid_t)-1;
|
||||
@@ -273,6 +275,79 @@ setperms(uid_t uid, gid_t gid) {
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
static isc_result_t
|
||||
connect_systemd_notify_unix(char *path) {
|
||||
struct sockaddr_un addr;
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
size_t len;
|
||||
|
||||
addr.sun_family = AF_UNIX;
|
||||
|
||||
len = strlcpy(addr.sun_path, path, sizeof(addr.sun_path));
|
||||
if (len >= sizeof(addr.sun_path)) {
|
||||
return ISC_R_NOSPACE;
|
||||
}
|
||||
|
||||
/* Convert abstract unix sockets */
|
||||
if (addr.sun_path[0] == '@') {
|
||||
addr.sun_path[0] = '\0';
|
||||
}
|
||||
|
||||
notify_fd = socket(AF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0);
|
||||
if (notify_fd < 0) {
|
||||
return isc_errno_toresult(errno);
|
||||
}
|
||||
|
||||
if (connect(notify_fd, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
|
||||
result = isc_errno_toresult(errno);
|
||||
close(notify_fd);
|
||||
notify_fd = -1;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
setup_systemd_notify(void) {
|
||||
isc_result_t result;
|
||||
char *path;
|
||||
|
||||
REQUIRE(notify_fd == -1);
|
||||
|
||||
path = getenv("NOTIFY_SOCKET");
|
||||
|
||||
/* systemd notification is not set, oh well. */
|
||||
if (path == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (path[0] == '/' || path[0] == '@') {
|
||||
result = connect_systemd_notify_unix(path);
|
||||
} else if (strncmp(path, "vsock", 5) == 0) {
|
||||
result = ISC_R_FAMILYNOSUPPORT;
|
||||
} else {
|
||||
result = ISC_R_INVALIDPROTO;
|
||||
}
|
||||
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
RUNTIME_CHECK(notify_fd == -1);
|
||||
isc_log_write(
|
||||
NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_MAIN,
|
||||
ISC_LOG_WARNING,
|
||||
"failed to connect to notification socket '%s': %s",
|
||||
path, isc_result_totext(result));
|
||||
} else {
|
||||
RUNTIME_CHECK(notify_fd != -1);
|
||||
isc_log_write(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_MAIN,
|
||||
ISC_LOG_INFO,
|
||||
"connected to notification socket '%s'", path);
|
||||
}
|
||||
}
|
||||
#else /* __linux__ */
|
||||
#define setup_systemd_notify(...)
|
||||
#endif /* __linux__ */
|
||||
|
||||
static void
|
||||
setup_syslog(const char *progname) {
|
||||
int options;
|
||||
@@ -287,6 +362,7 @@ setup_syslog(const char *progname) {
|
||||
void
|
||||
named_os_init(const char *progname) {
|
||||
setup_syslog(progname);
|
||||
setup_systemd_notify();
|
||||
#if HAVE_LIBCAP
|
||||
linux_initialprivs();
|
||||
#endif /* HAVE_LIBCAP */
|
||||
@@ -362,6 +438,13 @@ named_os_daemonize(void) {
|
||||
(void)dup2(devnullfd, STDERR_FILENO);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Will be closed from SOCK_CLOEXEC but should be set to -1 again before
|
||||
* reconnecting to the notification socket.
|
||||
*/
|
||||
notify_fd = -1;
|
||||
setup_systemd_notify();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -865,3 +948,38 @@ named_os_uname(void) {
|
||||
}
|
||||
return unamep;
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
void
|
||||
named_os_notify_systemd(const char *restrict format, ...) {
|
||||
char buffer[512];
|
||||
va_list ap;
|
||||
int len;
|
||||
|
||||
if (notify_fd == -1 || format == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
va_start(ap, format);
|
||||
len = vsnprintf(buffer, sizeof(buffer), format, ap);
|
||||
va_end(ap);
|
||||
|
||||
/* Be very loud if notification is too long */
|
||||
RUNTIME_CHECK(len > 0 && len < (int)sizeof(buffer));
|
||||
|
||||
if (write(notify_fd, buffer, len) != len) {
|
||||
isc_log_write(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_MAIN,
|
||||
ISC_LOG_ERROR,
|
||||
"failed writing to notification socket '%s'",
|
||||
isc_result_totext(isc_errno_toresult(errno)));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
named_os_notify_close(void) {
|
||||
if (notify_fd != -1) {
|
||||
close(notify_fd);
|
||||
notify_fd = -1;
|
||||
}
|
||||
}
|
||||
#endif /* __linux__ */
|
||||
|
@@ -28,10 +28,6 @@
|
||||
#include <fstrm.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIBSYSTEMD
|
||||
#include <systemd/sd-daemon.h>
|
||||
#endif
|
||||
|
||||
#include <isc/async.h>
|
||||
#include <isc/attributes.h>
|
||||
#include <isc/base64.h>
|
||||
@@ -9402,13 +9398,10 @@ view_loaded(void *arg) {
|
||||
ISC_LOG_NOTICE, "FIPS mode is %s",
|
||||
isc_crypto_fips_mode() ? "enabled" : "disabled");
|
||||
|
||||
#if HAVE_LIBSYSTEMD
|
||||
sd_notifyf(0,
|
||||
"READY=1\n"
|
||||
"STATUS=running\n"
|
||||
"MAINPID=%" PRId64 "\n",
|
||||
(int64_t)getpid());
|
||||
#endif /* HAVE_LIBSYSTEMD */
|
||||
named_os_notify_systemd("READY=1\n"
|
||||
"STATUS=running\n"
|
||||
"MAINPID=%" PRId64 "\n",
|
||||
(int64_t)getpid());
|
||||
|
||||
atomic_store(&server->reload_status, NAMED_RELOAD_DONE);
|
||||
|
||||
@@ -9547,9 +9540,8 @@ shutdown_server(void *arg) {
|
||||
bool flush = server->flushonshutdown;
|
||||
named_cache_t *nsc = NULL;
|
||||
|
||||
#if HAVE_LIBSYSTEMD
|
||||
sd_notify(0, "STOPPING=1\n");
|
||||
#endif /* HAVE_LIBSYSTEMD */
|
||||
named_os_notify_systemd("STOPPING=1\n");
|
||||
named_os_notify_close();
|
||||
|
||||
isc_signal_stop(server->sighup);
|
||||
isc_signal_destroy(&server->sighup);
|
||||
@@ -10041,17 +10033,11 @@ reload(named_server_t *server) {
|
||||
isc_result_t result;
|
||||
|
||||
atomic_store(&server->reload_status, NAMED_RELOAD_IN_PROGRESS);
|
||||
#if HAVE_LIBSYSTEMD
|
||||
char buf[512];
|
||||
int n = snprintf(buf, sizeof(buf),
|
||||
"RELOADING=1\n"
|
||||
"MONOTONIC_USEC=%" PRIu64 "\n"
|
||||
"STATUS=reload command received\n",
|
||||
(uint64_t)isc_time_monotonic() / NS_PER_US);
|
||||
if (n > 0 && (size_t)n < sizeof(buf)) {
|
||||
sd_notify(0, buf);
|
||||
}
|
||||
#endif /* HAVE_LIBSYSTEMD */
|
||||
|
||||
named_os_notify_systemd("RELOADING=1\n"
|
||||
"MONOTONIC_USEC=%" PRIu64 "\n"
|
||||
"STATUS=reload command received\n",
|
||||
(uint64_t)isc_time_monotonic() / NS_PER_US);
|
||||
|
||||
CHECK(loadconfig(server));
|
||||
|
||||
@@ -10066,12 +10052,10 @@ reload(named_server_t *server) {
|
||||
atomic_store(&server->reload_status, NAMED_RELOAD_FAILED);
|
||||
}
|
||||
cleanup:
|
||||
#if HAVE_LIBSYSTEMD
|
||||
sd_notifyf(0,
|
||||
"READY=1\n"
|
||||
"STATUS=reload command finished: %s\n",
|
||||
isc_result_totext(result));
|
||||
#endif /* HAVE_LIBSYSTEMD */
|
||||
named_os_notify_systemd("READY=1\n"
|
||||
"STATUS=reload command finished: %s\n",
|
||||
isc_result_totext(result));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -10542,17 +10526,11 @@ isc_result_t
|
||||
named_server_reconfigcommand(named_server_t *server) {
|
||||
isc_result_t result;
|
||||
atomic_store(&server->reload_status, NAMED_RELOAD_IN_PROGRESS);
|
||||
#if HAVE_LIBSYSTEMD
|
||||
char buf[512];
|
||||
int n = snprintf(buf, sizeof(buf),
|
||||
"RELOADING=1\n"
|
||||
"MONOTONIC_USEC=%" PRIu64 "\n"
|
||||
"STATUS=reconfig command received\n",
|
||||
(uint64_t)isc_time_monotonic() / NS_PER_US);
|
||||
if (n > 0 && (size_t)n < sizeof(buf)) {
|
||||
sd_notify(0, buf);
|
||||
}
|
||||
#endif /* HAVE_LIBSYSTEMD */
|
||||
|
||||
named_os_notify_systemd("RELOADING=1\n"
|
||||
"MONOTONIC_USEC=%" PRIu64 "\n"
|
||||
"STATUS=reconfig command received\n",
|
||||
(uint64_t)isc_time_monotonic() / NS_PER_US);
|
||||
|
||||
CHECK(loadconfig(server));
|
||||
|
||||
@@ -10567,12 +10545,10 @@ named_server_reconfigcommand(named_server_t *server) {
|
||||
atomic_store(&server->reload_status, NAMED_RELOAD_FAILED);
|
||||
}
|
||||
cleanup:
|
||||
#if HAVE_LIBSYSTEMD
|
||||
sd_notifyf(0,
|
||||
"READY=1\n"
|
||||
"STATUS=reconfig command finished: %s\n",
|
||||
isc_result_totext(result));
|
||||
#endif /* HAVE_LIBSYSTEMD */
|
||||
named_os_notify_systemd("READY=1\n"
|
||||
"STATUS=reconfig command finished: %s\n",
|
||||
isc_result_totext(result));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
20
configure.ac
20
configure.ac
@@ -859,26 +859,6 @@ AS_CASE([$with_zlib],
|
||||
AC_SUBST([ZLIB_CFLAGS])
|
||||
AC_SUBST([ZLIB_LIBS])
|
||||
|
||||
#
|
||||
# was --with-libsystemd specified?
|
||||
#
|
||||
# [pairwise: --with-libsystemd=auto, --with-libsystemd=yes, --without-libsystemd]
|
||||
AC_ARG_WITH([libsystemd],
|
||||
[AS_HELP_STRING([--with-libsystemd],
|
||||
[build with libsystemd integration [default=auto]])],
|
||||
[], [with_libsystemd=auto])
|
||||
|
||||
AS_CASE([$with_libsystemd],
|
||||
[no],[],
|
||||
[auto],[PKG_CHECK_MODULES([LIBSYSTEMD], [libsystemd],
|
||||
[AC_DEFINE([HAVE_LIBSYSTEMD], [1], [Use libsystemd library])],
|
||||
[:])],
|
||||
[yes],[PKG_CHECK_MODULES([LIBSYSTEMD], [libsystemd],
|
||||
[AC_DEFINE([HAVE_LIBSYSTEMD], [1], [Use libsystemd library])])],
|
||||
[AC_MSG_ERROR([Specifying libsystemd installation path is not supported, adjust PKG_CONFIG_PATH instead])])
|
||||
AC_SUBST([LIBSYSTEMD_CFLAGS])
|
||||
AC_SUBST([LIBSYSTEMD_LIBS])
|
||||
|
||||
#
|
||||
# Check if the system supports glibc-compatible backtrace() function.
|
||||
#
|
||||
|
Reference in New Issue
Block a user