ubusd: fix systemd socket activation support

62cdfc3 added systemd units including a ubus.socket unit, but didn't
actually add socket activation support to ubusd. This would cause the first
connection that activated ubusd to hang (as ubusd ignored it), and stopping
ubusd would break it completely (as ubusd removed the socket file).

The ENABLE_SYSTEMD default is changed to OFF as the socket activation uses
libsystemd, so setting ENABLE_SYSTEMD to ON will now require libsystemd.

Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
This commit is contained in:
Matthias Schiffer 2016-05-24 02:01:48 +02:00 committed by John Crispin
parent 3b8d4b5653
commit 964adfdd39
2 changed files with 42 additions and 12 deletions

View file

@ -5,7 +5,7 @@ ADD_DEFINITIONS(-Os -Wall -Werror --std=gnu99 -g3 -Wmissing-declarations)
OPTION(BUILD_LUA "build Lua plugin" ON)
OPTION(BUILD_EXAMPLES "build examples" ON)
OPTION(ENABLE_SYSTEMD "systemd support" ON)
OPTION(ENABLE_SYSTEMD "systemd support" OFF)
SET(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "")
SET(UBUS_UNIX_SOCKET "/var/run/ubus.sock")
@ -60,8 +60,13 @@ SET(UBUSD_BINARY "${CMAKE_INSTALL_PREFIX}/sbin/ubusd")
# do this after the installs so we have the proper paths
IF(ENABLE_SYSTEMD)
INCLUDE(FindPkgConfig)
PKG_CHECK_MODULES(SYSTEMD systemd)
IF(SYSTEMD_FOUND)
ADD_SUBDIRECTORY(systemd)
ENDIF()
PKG_CHECK_MODULES(SYSTEMD libsystemd REQUIRED)
SET_PROPERTY(TARGET ubusd APPEND PROPERTY COMPILE_FLAGS "${SYSTEMD_CFLAGS}")
SET_PROPERTY(TARGET ubusd APPEND PROPERTY LINK_FLAGS "${SYSTEMD_LDFLAGS}")
SET_PROPERTY(TARGET ubusd APPEND PROPERTY INCLUDE_DIRECTORIES ${SYSTEMD_INCLUDE_DIRS})
TARGET_LINK_LIBRARIES(ubusd ${SYSTEMD_LIBRARIES})
ADD_DEFINITIONS( -DENABLE_SYSTEMD)
ADD_SUBDIRECTORY(systemd)
ENDIF()

39
ubusd.c
View file

@ -22,6 +22,9 @@
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#ifdef ENABLE_SYSTEMD
#include <systemd/sd-daemon.h>
#endif
#include <libubox/blob.h>
#include <libubox/uloop.h>
@ -380,8 +383,12 @@ static void sighup_handler(int sig)
int main(int argc, char **argv)
{
const char *ubus_socket = UBUS_UNIX_SOCKET;
bool remove_socket = true;
int ret = 0;
int ch;
#ifdef ENABLE_SYSTEMD
int n_fds;
#endif
signal(SIGPIPE, SIG_IGN);
signal(SIGHUP, sighup_handler);
@ -402,19 +409,37 @@ int main(int argc, char **argv)
}
}
unlink(ubus_socket);
umask(0111);
server_fd.fd = usock(USOCK_UNIX | USOCK_SERVER | USOCK_NONBLOCK, ubus_socket, NULL);
if (server_fd.fd < 0) {
perror("usock");
ret = -1;
#ifdef ENABLE_SYSTEMD
n_fds = sd_listen_fds(1);
if (n_fds > 1) {
fprintf(stderr, "Too many file descriptors received.\n");
ret = -1;
goto out;
} else if (n_fds == 1) {
server_fd.fd = SD_LISTEN_FDS_START + 0;
fcntl(server_fd.fd, F_SETFD, fcntl(server_fd.fd, F_GETFD) | FD_CLOEXEC);
fcntl(server_fd.fd, F_SETFL, fcntl(server_fd.fd, F_GETFL) | O_NONBLOCK);
remove_socket = false;
} else
#endif
{
unlink(ubus_socket);
umask(0111);
server_fd.fd = usock(USOCK_UNIX | USOCK_SERVER | USOCK_NONBLOCK, ubus_socket, NULL);
if (server_fd.fd < 0) {
perror("usock");
ret = -1;
goto out;
}
}
uloop_fd_add(&server_fd, ULOOP_READ | ULOOP_EDGE_TRIGGER);
ubusd_acl_load();
uloop_run();
unlink(ubus_socket);
if (remove_socket)
unlink(ubus_socket);
out:
uloop_done();