From 7338b16c180a879745ecf6dcd6a7d490081dbb01 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Mon, 13 Feb 2012 20:48:51 +0100 Subject: [PATCH] listen: implement systemd socket activation --- INSTALL | 3 +++ Makefile.am | 1 + NEWS | 1 + configure.ac | 12 ++++++++++++ doc/user.xml | 41 +++++++++++++++++++++++++++++++++++++++++ src/listen.c | 36 ++++++++++++++++++++++++++++++++++++ 6 files changed, 94 insertions(+) diff --git a/INSTALL b/INSTALL index e9c802442..b07e1284c 100644 --- a/INSTALL +++ b/INSTALL @@ -139,6 +139,9 @@ For the sticker database. libcdio - http://www.gnu.org/software/libcdio/ For playing audio CDs. +libsystemd-daemon - http://freedesktop.org/wiki/Software/systemd/ +For systemd activation. + pkg-config ---------- diff --git a/Makefile.am b/Makefile.am index d82306e97..e113e8b61 100644 --- a/Makefile.am +++ b/Makefile.am @@ -34,6 +34,7 @@ src_mpd_LDADD = \ $(FILTER_LIBS) \ $(ENCODER_LIBS) \ $(MIXER_LIBS) \ + $(SYSTEMD_DAEMON_LIBS) \ $(GLIB_LIBS) mpd_headers = \ diff --git a/NEWS b/NEWS index f50996679..2bd1e55f1 100644 --- a/NEWS +++ b/NEWS @@ -34,6 +34,7 @@ ver 0.17 (2011/??/??) * cue: show CUE track numbers * allow port specification in "bind_to_address" settings * support floating point samples +* systemd socket activation ver 0.16.8 (2012/??/??) diff --git a/configure.ac b/configure.ac index 3a1bc465a..f1de64575 100644 --- a/configure.ac +++ b/configure.ac @@ -353,6 +353,11 @@ AC_ARG_ENABLE(sqlite, [enable support for the SQLite database]),, [enable_sqlite=auto]) +AC_ARG_ENABLE(systemd-daemon, + AS_HELP_STRING([--enable-systemd-daemon], + [use the systemd daemon library (default=auto)]),, + [enable_systemd_daemon=auto]) + AC_ARG_ENABLE(tcp, AS_HELP_STRING([--disable-tcp], [disable support for clients connecting via TCP (default: enable)]),, @@ -495,6 +500,13 @@ if AC_MSG_ERROR([No client interfaces configured!]) fi +MPD_AUTO_PKG(systemd_daemon, SYSTEMD_DAEMON, libsystemd-daemon, + [systemd activation], [libsystemd-daemon not found]) +AM_CONDITIONAL(ENABLE_SYSTEMD_DAEMON, test x$enable_systemd_daemon = xyes) +if test x$enable_systemd_daemon = xyes; then + AC_DEFINE([ENABLE_SYSTEMD_DAEMON], 1, [Define to use the systemd daemon library]) +fi + dnl --------------------------------------------------------------------------- dnl LIBC Features dnl --------------------------------------------------------------------------- diff --git a/doc/user.xml b/doc/user.xml index d0db21ef7..427e561c5 100644 --- a/doc/user.xml +++ b/doc/user.xml @@ -99,6 +99,47 @@ cd mpd-version make install + +
+ <filename>systemd</filename> socket activation + + + Using systemd, you can launch + mpd on demand when the first client + attempts to connect. Create two files in + /etc/systemd/system/; first + mpd.socket: + + + [Socket] +ListenStream=/run/mpd.socket +ListenStream=6600 +[Install] +WantedBy=sockets.target + + + Now create mpd.service: + + + [Unit] +Description=Music Player Daemon +After=sound.target +[Service] +ExecStart=/usr/bin/mpd --stdout --no-daemon + + + Start the socket: + + + systemctl enable mpd.socket +systemctl start mpd.socket + + + In this configuration, mpd will ignore + the bind_to_address and + port settings. + +
diff --git a/src/listen.c b/src/listen.c index 5c958507d..e2a40e93f 100644 --- a/src/listen.c +++ b/src/listen.c @@ -28,6 +28,10 @@ #include #include +#ifdef ENABLE_SYSTEMD_DAEMON +#include +#endif + #undef G_LOG_DOMAIN #define G_LOG_DOMAIN "listen" @@ -61,6 +65,30 @@ listen_add_config_param(unsigned int port, } } +static bool +listen_systemd_activation(GError **error_r) +{ +#ifdef ENABLE_SYSTEMD_DAEMON + int n = sd_listen_fds(true); + if (n <= 0) { + if (n < 0) + g_warning("sd_listen_fds() failed: %s", + g_strerror(-n)); + return false; + } + + for (int i = SD_LISTEN_FDS_START, end = SD_LISTEN_FDS_START + n; + i != end; ++i) + if (!server_socket_add_fd(listen_socket, i, error_r)) + return false; + + return true; +#else + (void)error_r; + return false; +#endif +} + bool listen_global_init(GError **error_r) { @@ -72,6 +100,14 @@ listen_global_init(GError **error_r) listen_socket = server_socket_new(listen_callback, NULL); + if (listen_systemd_activation(&error)) + return true; + + if (error != NULL) { + g_propagate_error(error_r, error); + return false; + } + if (param != NULL) { /* "bind_to_address" is configured, create listeners for all values */