journald: add ability to activate by varlink socket

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)
This commit is contained in:
Lennart Poettering 2019-11-27 14:47:37 +01:00
parent 65c398c031
commit dc5437c78b
5 changed files with 47 additions and 12 deletions

View 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)

View 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;

View 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', ''],

View File

@ -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

View 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