https://gitlab.nic.cz/knot/knot-resolver/-/merge_requests/1608 Draft: daemon: add sd_notify alternative This allows kresd to run even if libsystemd is not available. diff --git a/daemon/main.c b/daemon/main.c index 44b8ae4c1b745c19ae91f6c9119b895d7738947f..230b1e453217682df387165c08f4115d795cb983 100644 --- a/daemon/main.c +++ b/daemon/main.c @@ -36,6 +36,8 @@ #include #if ENABLE_LIBSYSTEMD #include +#else +static int notify_ready(const char *state); #endif #include @@ -68,6 +70,7 @@ KR_EXPORT const char *malloc_conf = "narenas:1"; #define TCP_BACKLOG_DEFAULT 128 #endif + /** I don't know why linker is dropping these functions otherwise. TODO: revisit. */ KR_EXPORT void kr_misc_unused(void) { @@ -209,6 +212,8 @@ static int run_worker(uv_loop_t *loop, bool leader, struct args *args) /* Notify supervisor. */ #if ENABLE_LIBSYSTEMD sd_notify(0, "READY=1"); +#else + notify_ready("READY=1"); #endif /* Run event loop */ uv_run(loop, UV_RUN_DEFAULT); @@ -414,6 +419,47 @@ static int start_listening(flagged_fd_array_t *fds) { return some_bad_ret; } +#if !ENABLE_LIBSYSTEMD +/* Notify supervisord about successful inicialization + * @note tested only on an abstract address in $NOTIFY_SOCKET*/ +static int notify_ready(const char *state) +{ + int sockfd; + struct sockaddr_un addr; + char *socket_path = getenv("NOTIFY_SOCKET"); + if (!socket_path) { + kr_log_error(WORKER, "Failed retrieving env variable $NOTIFY_SOCKET\n"); + return EXIT_FAILURE; + } + if ((sockfd = socket(AF_UNIX, SOCK_DGRAM, 0)) == -1) { + kr_log_error(WORKER, "Failed to create unix socket at $NOTIFY_SOCKET ('%s'): %s\n", + socket_path, strerror(errno)); + return EXIT_FAILURE; + } + + addr.sun_family = AF_UNIX; + + int addrlen; + if (socket_path[0] == '@') { + addr.sun_path[0] = '\0'; + strncpy(&addr.sun_path[1], socket_path + 1, sizeof(addr.sun_path) - 2); + addrlen = offsetof(struct sockaddr_un, sun_path) + strlen(addr.sun_path + 1) + 1; + } else { + strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path) - 1); + addrlen = offsetof(struct sockaddr_un, sun_path) + strlen(addr.sun_path) + 1; + } + if (sendto(sockfd, state, strlen(state), 0, &addr, addrlen) == -1) { + kr_log_error(WORKER, "Failed to send notify message to '%s': %s\n", + socket_path, strerror(errno)); + close(sockfd); + return EXIT_FAILURE; + } + + close(sockfd); + return kr_ok(); +} +#endif /* if !ENABLE_LIBSYSTEMD */ + /* Drop POSIX 1003.1e capabilities. */ static void drop_capabilities(void) {