From: Lennart Poettering Date: Wed, 24 Jan 2018 16:42:12 +0000 (+0100) Subject: pid1: make use of new "prohibit_ipc" logging flag in PID 1 X-Git-Tag: v237~31^2~2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=d075092f14ce02df39aee02bca2eb8a577a69076;p=thirdparty%2Fsystemd.git pid1: make use of new "prohibit_ipc" logging flag in PID 1 Let's set it initially, and then toggle it only when we know its safe. --- diff --git a/src/core/main.c b/src/core/main.c index 9ecb8e98355..245b4c076cc 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 4130b249729..2952f217c32 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(); + if (!u) + return false; + if (SERVICE(u)->state != SERVICE_RUNNING) + return false; + + 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; - } - /* Hmm, OK, so the socket is fully up and the service is up - * too, then let's make use of the thing. */ - log_open(); + 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) {