]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
journald: add ability to activate by varlink socket
authorLennart Poettering <lennart@poettering.net>
Wed, 27 Nov 2019 13:47:37 +0000 (14:47 +0100)
committerLennart Poettering <lennart@poettering.net>
Fri, 31 Jan 2020 14:03:55 +0000 (15:03 +0100)
If we have exit on idle, then operations such as "journalctl
--namespace=foo --rotate" should work even if the journal daemon is
currently not running.

(Note that we don't do activation by varlink for the main instance of
journald, I am not sure the deadlocks it might introduce are worth it)

src/core/unit.c
src/journal/journald-server.c
units/meson.build
units/systemd-journald-varlink@.socket [new file with mode: 0644]
units/systemd-journald@.service.in

index 408970233551b576314527af1430c89fe6b4eee0..6b97c35ffa1ebd639ab9dd05d644bc26b8baeb53 100644 (file)
@@ -1067,7 +1067,7 @@ int unit_add_exec_dependencies(Unit *u, ExecContext *c) {
          * is run first. */
 
         if (c->log_namespace) {
-                _cleanup_free_ char *socket_unit = NULL;
+                _cleanup_free_ char *socket_unit = NULL, *varlink_socket_unit = NULL;
 
                 r = unit_name_build_from_type("systemd-journald", c->log_namespace, UNIT_SOCKET, &socket_unit);
                 if (r < 0)
@@ -1076,6 +1076,14 @@ int unit_add_exec_dependencies(Unit *u, ExecContext *c) {
                 r = unit_add_two_dependencies_by_name(u, UNIT_AFTER, UNIT_REQUIRES, socket_unit, true, UNIT_DEPENDENCY_FILE);
                 if (r < 0)
                         return r;
+
+                r = unit_name_build_from_type("systemd-journald-varlink", c->log_namespace, UNIT_SOCKET, &varlink_socket_unit);
+                if (r < 0)
+                        return r;
+
+                r = unit_add_two_dependencies_by_name(u, UNIT_AFTER, UNIT_REQUIRES, varlink_socket_unit, true, UNIT_DEPENDENCY_FILE);
+                if (r < 0)
+                        return r;
         } else
                 r = unit_add_dependency_by_name(u, UNIT_AFTER, SPECIAL_JOURNALD_SOCKET, true, UNIT_DEPENDENCY_FILE);
         if (r < 0)
index 3c2f55941beb056fc409ad00be7e2cea602024c4..eb124aa73f4c05b56c31a321cad14d2adcc57561 100644 (file)
@@ -2036,8 +2036,7 @@ static void vl_disconnect(VarlinkServer *server, Varlink *link, void *userdata)
         (void) server_start_or_stop_idle_timer(s); /* maybe we are idle now */
 }
 
-static int server_open_varlink(Server *s) {
-        const char *fn;
+static int server_open_varlink(Server *s, const char *socket, int fd) {
         int r;
 
         assert(s);
@@ -2065,9 +2064,10 @@ static int server_open_varlink(Server *s) {
         if (r < 0)
                 return r;
 
-        fn = strjoina(s->runtime_directory, "/io.systemd.journal");
-
-        r = varlink_server_listen_address(s->varlink_server, fn, 0600);
+        if (fd < 0)
+                r = varlink_server_listen_address(s->varlink_server, socket, 0600);
+        else
+                r = varlink_server_listen_fd(s->varlink_server, fd);
         if (r < 0)
                 return r;
 
@@ -2186,10 +2186,10 @@ static int set_namespace(Server *s, const char *namespace) {
 }
 
 int server_init(Server *s, const char *namespace) {
-        const char *native_socket, *syslog_socket, *stdout_socket, *e;
+        const char *native_socket, *syslog_socket, *stdout_socket, *varlink_socket, *e;
         _cleanup_fdset_free_ FDSet *fds = NULL;
+        int n, r, fd, varlink_fd = -1;
         bool no_sockets;
-        int n, r, fd;
 
         assert(s);
 
@@ -2291,6 +2291,7 @@ int server_init(Server *s, const char *namespace) {
         native_socket = strjoina(s->runtime_directory, "/socket");
         stdout_socket = strjoina(s->runtime_directory, "/stdout");
         syslog_socket = strjoina(s->runtime_directory, "/dev-log");
+        varlink_socket = strjoina(s->runtime_directory, "/io.systemd.journal");
 
         for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd++) {
 
@@ -2318,6 +2319,13 @@ int server_init(Server *s, const char *namespace) {
 
                         s->syslog_fd = fd;
 
+                } else if (sd_is_socket_unix(fd, SOCK_STREAM, 1, varlink_socket, 0) > 0) {
+
+                        if (varlink_fd >= 0)
+                                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+                                                       "Too many varlink sockets passed.");
+
+                        varlink_fd = fd;
                 } else if (sd_is_socket(fd, AF_NETLINK, SOCK_RAW, -1) > 0) {
 
                         if (s->audit_fd >= 0)
@@ -2348,7 +2356,7 @@ int server_init(Server *s, const char *namespace) {
                 fds = fdset_free(fds);
         }
 
-        no_sockets = s->native_fd < 0 && s->stdout_fd < 0 && s->syslog_fd < 0 && s->audit_fd < 0;
+        no_sockets = s->native_fd < 0 && s->stdout_fd < 0 && s->syslog_fd < 0 && s->audit_fd < 0 && varlink_fd < 0;
 
         /* always open stdout, syslog, native, and kmsg sockets */
 
@@ -2379,7 +2387,7 @@ int server_init(Server *s, const char *namespace) {
                         return r;
         }
 
-        r = server_open_varlink(s);
+        r = server_open_varlink(s, varlink_socket, varlink_fd);
         if (r < 0)
                 return r;
 
index c0b69566d14131bc81f6b80bd31169844ef52a79..0dc85ac64a3c88cb28a19429b610d3af89bd130c 100644 (file)
@@ -115,6 +115,7 @@ units = [
         ['systemd-machine-id-commit.service',   '',
          'sysinit.target.wants/'],
         ['systemd-journald@.socket',            ''],
+        ['systemd-journald-varlink@.socket',    ''],
         ['systemd-networkd.socket',             'ENABLE_NETWORKD'],
         ['systemd-poweroff.service',            ''],
         ['systemd-reboot.service',              ''],
diff --git a/units/systemd-journald-varlink@.socket b/units/systemd-journald-varlink@.socket
new file mode 100644 (file)
index 0000000..b6730c2
--- /dev/null
@@ -0,0 +1,18 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Journal Varlink Socket for Namespace %i
+Documentation=man:systemd-journald.service(8) man:journald.conf(5)
+StopWhenUnneeded=yes
+
+[Socket]
+Service=systemd-journald@%i.service
+ListenStream=/run/systemd/journal.%i/io.systemd.journal
+SocketMode=0600
index 43082fa41b8e505490d5d3b412804b8c2a53e172..e7ea919328081e0660003d9e03584eb8f1bb27ab 100644 (file)
@@ -10,8 +10,8 @@
 [Unit]
 Description=Journal Service for Namespace %i
 Documentation=man:systemd-journald.service(8) man:journald.conf(5)
-Requires=systemd-journald@%i.socket
-After=systemd-journald@%i.socket
+Requires=systemd-journald@%i.socket systemd-journald-varlink@%i.socket
+After=systemd-journald@%i.socket systemd-journald-varlink@%i.socket
 
 [Service]
 CapabilityBoundingSet=CAP_SYS_ADMIN CAP_DAC_OVERRIDE CAP_SYS_PTRACE CAP_CHOWN CAP_DAC_READ_SEARCH CAP_FOWNER CAP_SETUID CAP_SETGID CAP_MAC_OVERRIDE