diff options
Diffstat (limited to 'src/userdb/userdbd-manager.c')
-rw-r--r-- | src/userdb/userdbd-manager.c | 108 |
1 files changed, 70 insertions, 38 deletions
diff --git a/src/userdb/userdbd-manager.c b/src/userdb/userdbd-manager.c index 359c827..5925602 100644 --- a/src/userdb/userdbd-manager.c +++ b/src/userdb/userdbd-manager.c @@ -4,6 +4,7 @@ #include "sd-daemon.h" +#include "build-path.h" #include "common-signal.h" #include "env-util.h" #include "fd-util.h" @@ -14,6 +15,7 @@ #include "signal-util.h" #include "socket-util.h" #include "stdio-util.h" +#include "strv.h" #include "umask-util.h" #include "userdbd-manager.h" @@ -185,17 +187,19 @@ static int start_one_worker(Manager *m) { _exit(EXIT_FAILURE); } - if (setenv("USERDB_FIXED_WORKER", one_zero(fixed), 1) < 0) { log_error_errno(errno, "Failed to set $USERDB_FIXED_WORKER: %m"); _exit(EXIT_FAILURE); } - /* execl("/home/lennart/projects/systemd/build/systemd-userwork", "systemd-userwork", "xxxxxxxxxxxxxxxx", NULL); /\* With some extra space rename_process() can make use of *\/ */ - /* execl("/usr/bin/valgrind", "valgrind", "/home/lennart/projects/systemd/build/systemd-userwork", "systemd-userwork", "xxxxxxxxxxxxxxxx", NULL); /\* With some extra space rename_process() can make use of *\/ */ + r = setenv_systemd_log_level(); + if (r < 0) { + log_error_errno(r, "Failed to set $SYSTEMD_LOG_LEVEL: %m"); + _exit(EXIT_FAILURE); + } - execl(SYSTEMD_USERWORK_PATH, "systemd-userwork", "xxxxxxxxxxxxxxxx", NULL); /* With some extra space rename_process() can make use of */ - log_error_errno(errno, "Failed start worker process: %m"); + r = invoke_callout_binary(SYSTEMD_USERWORK_PATH, STRV_MAKE(SYSTEMD_USERWORK_PATH, "xxxxxxxxxxxxxxxx")); /* With some extra space rename_process() can make use of */ + log_error_errno(r, "Failed start worker process: %m"); _exit(EXIT_FAILURE); } @@ -265,57 +269,85 @@ static int start_workers(Manager *m, bool explicit_request) { return 0; } -int manager_startup(Manager *m) { - int n, r; +static int manager_make_listen_socket(Manager *m) { + static const union sockaddr_union sockaddr = { + .un.sun_family = AF_UNIX, + .un.sun_path = "/run/systemd/userdb/io.systemd.Multiplexer", + }; + int r; assert(m); - assert(m->listen_fd < 0); - n = sd_listen_fds(false); + if (m->listen_fd >= 0) + return 0; + + r = mkdir_p("/run/systemd/userdb", 0755); + if (r < 0) + return log_error_errno(r, "Failed to create /run/systemd/userdb: %m"); + + m->listen_fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0); + if (m->listen_fd < 0) + return log_error_errno(errno, "Failed to bind on socket: %m"); + + (void) sockaddr_un_unlink(&sockaddr.un); + + WITH_UMASK(0000) + if (bind(m->listen_fd, &sockaddr.sa, SOCKADDR_UN_LEN(sockaddr.un)) < 0) + return log_error_errno(errno, "Failed to bind socket: %m"); + + FOREACH_STRING(alias, + "/run/systemd/userdb/io.systemd.NameServiceSwitch", + "/run/systemd/userdb/io.systemd.DropIn") { + + r = symlink_idempotent("io.systemd.Multiplexer", alias, /* make_relative= */ false); + if (r < 0) + return log_error_errno(r, "Failed to symlink '%s': %m", alias); + } + + if (listen(m->listen_fd, SOMAXCONN_DELUXE) < 0) + return log_error_errno(errno, "Failed to listen on socket: %m"); + + return 1; +} + +static int manager_scan_listen_fds(Manager *m) { + int n; + + assert(m); + + n = sd_listen_fds(/* unset_environment= */ true); if (n < 0) return log_error_errno(n, "Failed to determine number of passed file descriptors: %m"); if (n > 1) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Expected one listening fd, got %i.", n); if (n == 1) m->listen_fd = SD_LISTEN_FDS_START; - else { - static const union sockaddr_union sockaddr = { - .un.sun_family = AF_UNIX, - .un.sun_path = "/run/systemd/userdb/io.systemd.Multiplexer", - }; - - r = mkdir_p("/run/systemd/userdb", 0755); - if (r < 0) - return log_error_errno(r, "Failed to create /run/systemd/userdb: %m"); - - m->listen_fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0); - if (m->listen_fd < 0) - return log_error_errno(errno, "Failed to bind on socket: %m"); - (void) sockaddr_un_unlink(&sockaddr.un); + return 0; +} - WITH_UMASK(0000) - if (bind(m->listen_fd, &sockaddr.sa, SOCKADDR_UN_LEN(sockaddr.un)) < 0) - return log_error_errno(errno, "Failed to bind socket: %m"); +int manager_startup(Manager *m) { + int r; - r = symlink_idempotent("io.systemd.Multiplexer", - "/run/systemd/userdb/io.systemd.NameServiceSwitch", false); - if (r < 0) - return log_error_errno(r, "Failed to bind io.systemd.Multiplexer: %m"); + assert(m); + assert(m->listen_fd < 0); - r = symlink_idempotent("io.systemd.Multiplexer", - "/run/systemd/userdb/io.systemd.DropIn", false); - if (r < 0) - return log_error_errno(r, "Failed to bind io.systemd.Multiplexer: %m"); + r = manager_scan_listen_fds(m); + if (r < 0) + return r; - if (listen(m->listen_fd, SOMAXCONN_DELUXE) < 0) - return log_error_errno(errno, "Failed to listen on socket: %m"); - } + r = manager_make_listen_socket(m); + if (r < 0) + return r; /* Let's make sure every accept() call on this socket times out after 25s. This allows workers to be * GC'ed on idle */ if (setsockopt(m->listen_fd, SOL_SOCKET, SO_RCVTIMEO, TIMEVAL_STORE(LISTEN_TIMEOUT_USEC), sizeof(struct timeval)) < 0) return log_error_errno(errno, "Failed to se SO_RCVTIMEO: %m"); - return start_workers(m, /* explicit_request= */ false); + r = start_workers(m, /* explicit_request= */ false); + if (r < 0) + return r; + + return 0; } |