Auto-detect and link libsystemd at compile-time

This adds Makefile/build-system support for USE_SYSTEMD=(yes|no|*). This
variable's value determines whether or not libsystemd will be linked at
build-time.

If USE_SYSTEMD is set to "yes", make will use PKG_CONFIG to check for
libsystemd's presence, and fail the build early if it isn't
installed/detected properly.

If USE_SYSTEM is set to "no", libsystemd will *not* be linked, even if
support for it is available on the system redis is being built on.

For any other value that USE_SYSTEM might assume (e.g. "auto"),
PKG_CONFIG will try to determine libsystemd's presence, and set up the
build process to link against it, if it was indicated as being
installed/available.

This approach has a number of repercussions of its own, most importantly
the following: If you build redis on a system that actually has systemd
support, but no libsystemd-dev package(s) installed, you'll end up
*without* support for systemd notification/status reporting support in
redis-server. This changes established runtime behaviour.

I'm not sure if the build system and/or the server binary should
indicate this. I'm also wondering if not actually having
systemd-notify-support, but requesting it via the server's config,
should result in a fatal error now.
This commit is contained in:
Johannes Truschnigg 2019-05-30 18:44:17 +02:00 committed by max ulidtko
parent ec5681f0f1
commit 129d14e143
3 changed files with 34 additions and 27 deletions

View File

@ -32,6 +32,7 @@ OPT=$(OPTIMIZATION)
PREFIX?=/usr/local
INSTALL_BIN=$(PREFIX)/bin
INSTALL=install
PKG_CONFIG?=pkg-config
# Default allocator defaults to Jemalloc if it's not an ARM
MALLOC=libc
@ -131,6 +132,30 @@ endif
# Include paths to dependencies
FINAL_CFLAGS+= -I../deps/hiredis -I../deps/linenoise -I../deps/lua/src
# Determine systemd support and/or build preference (defaulting to auto-detection)
BUILD_WITH_SYSTEMD=no
# If 'USE_SYSTEMD' in the environment is neither "no" nor "yes", try to
# auto-detect libsystemd's presence and link accordingly.
ifneq ($(USE_SYSTEMD),no)
LIBSYSTEMD_PKGCONFIG := $(shell $(PKG_CONFIG) --exists libsystemd && echo $$?)
# If libsystemd cannot be detected, continue building without support for it
# (unless a later check tells us otherwise)
ifeq ($(LIBSYSTEMD_PKGCONFIG),0)
BUILD_WITH_SYSTEMD=yes
endif
endif
ifeq ($(USE_SYSTEMD),yes)
ifneq ($(LIBSYSTEMD_PKGCONFIG),0)
$(error USE_SYSTEMD is set to "$(USE_SYSTEMD)", but $(PKG_CONFIG) cannot find libsystemd)
endif
# Force building with libsystemd
BUILD_WITH_SYSTEMD=yes
endif
ifeq ($(BUILD_WITH_SYSTEMD),yes)
FINAL_LIBS+=$(shell $(PKG_CONFIG) --libs libsystemd)
FINAL_CFLAGS+= -DHAVE_LIBSYSTEMD
endif
ifeq ($(MALLOC),tcmalloc)
FINAL_CFLAGS+= -DUSE_TCMALLOC
FINAL_LIBS+= -ltcmalloc

View File

@ -55,7 +55,6 @@
#include <sys/utsname.h>
#include <locale.h>
#include <sys/socket.h>
#include <dlfcn.h>
/* Our shared "common" objects */
@ -4876,37 +4875,16 @@ int redisSupervisedUpstart(void) {
int redisCommunicateSystemd(const char *sd_notify_msg) {
const char *notify_socket = getenv("NOTIFY_SOCKET");
int (*dl_sd_notify)(int unset_environment, const char *state);
char *error;
void *handle;
if (!notify_socket) {
serverLog(LL_WARNING,
"systemd supervision requested, but NOTIFY_SOCKET not found");
return 0;
}
handle = dlopen("libsystemd.so.0", RTLD_LAZY);
if (!handle) {
serverLog(LL_WARNING,
"systemd supervision requested, but could not dlopen() libsystemd.so");
(void) dlerror();
return 0;
}
(void) dlerror();
*(void **)(&dl_sd_notify) = dlsym(handle, "sd_notify");
error = dlerror();
if (error != NULL) {
serverLog(LL_WARNING,
"systemd supervision requested, but could not load sd_notify(3) from libsystemd.so");
dlclose(handle);
return 0;
}
(void) (*dl_sd_notify)(0, sd_notify_msg);
dlclose(handle);
#ifdef HAVE_LIBSYSTEMD
(void) sd_notify(0, sd_notify_msg);
#else
UNUSED(sd_notify_msg);
#endif
return 0;
}

View File

@ -49,6 +49,10 @@
#include <lua.h>
#include <signal.h>
#ifdef HAVE_LIBSYSTEMD
#include <systemd/sd-daemon.h>
#endif
typedef long long mstime_t; /* millisecond time type. */
typedef long long ustime_t; /* microsecond time type. */