diff --git a/src/core/main.c b/src/core/main.c index 9ecb8e9835..245b4c076c 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -2335,6 +2335,10 @@ int main(int argc, char *argv[]) { /* Disable the umask logic */ umask(0); + /* Make sure that at least initially we do not ever log to journald/syslogd, because it might not be activated + * yet (even though the log socket for it exists). */ + log_set_prohibit_ipc(true); + /* Always reopen /dev/console when running as PID 1 or one of its pre-execve() children. This is * important so that we never end up logging to any foreign stderr, for example if we have to log in a * child process right before execve()'ing the actual binary, at a point in time where socket diff --git a/src/core/manager.c b/src/core/manager.c index 4130b24972..2952f217c3 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -3132,6 +3132,9 @@ int manager_reload(Manager *m) { manager_vacuum_uid_refs(m); manager_vacuum_gid_refs(m); + /* It might be safe to log to the journal now. */ + manager_recheck_journal(m); + /* Sync current state of bus names with our set of listening units */ if (m->api_bus) manager_sync_bus_names(m, m->api_bus); @@ -3482,29 +3485,52 @@ int manager_set_default_rlimits(Manager *m, struct rlimit **default_rlimit) { return 0; } -void manager_recheck_journal(Manager *m) { +static bool manager_journal_is_running(Manager *m) { Unit *u; assert(m); + /* If we are the user manager we can safely assume that the journal is up */ if (!MANAGER_IS_SYSTEM(m)) - return; + return true; + /* Check that the socket is not only up, but in RUNNING state */ u = manager_get_unit(m, SPECIAL_JOURNALD_SOCKET); - if (u && SOCKET(u)->state != SOCKET_RUNNING) { - log_close_journal(); - return; - } + if (!u) + return false; + if (SOCKET(u)->state != SOCKET_RUNNING) + return false; + /* Similar, check if the daemon itself is fully up, too */ u = manager_get_unit(m, SPECIAL_JOURNALD_SERVICE); - if (u && SERVICE(u)->state != SERVICE_RUNNING) { - log_close_journal(); - return; - } + if (!u) + return false; + if (SERVICE(u)->state != SERVICE_RUNNING) + return false; - /* Hmm, OK, so the socket is fully up and the service is up - * too, then let's make use of the thing. */ - log_open(); + return true; +} + +void manager_recheck_journal(Manager *m) { + + assert(m); + + /* Don't bother with this unless we are in the special situation of being PID 1 */ + if (getpid_cached() != 1) + return; + + if (manager_journal_is_running(m)) { + + /* The journal is fully and entirely up? If so, let's permit logging to it, if that's configured. */ + log_set_prohibit_ipc(false); + log_open(); + } else { + + /* If the journal is down, don't ever log to it, otherwise we might end up deadlocking ourselves as we + * might trigger an activation ourselves we can't fulfill */ + log_set_prohibit_ipc(true); + log_close_journal(); + } } void manager_set_show_status(Manager *m, ShowStatus mode) {