]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
pid1: make use of new "prohibit_ipc" logging flag in PID 1
authorLennart Poettering <lennart@poettering.net>
Wed, 24 Jan 2018 16:42:12 +0000 (17:42 +0100)
committerLennart Poettering <lennart@poettering.net>
Wed, 24 Jan 2018 17:22:56 +0000 (18:22 +0100)
Let's set it initially, and then toggle it only when we know its safe.

src/core/main.c
src/core/manager.c

index 9ecb8e983559019b8fe2c99a34a34292fa601f78..245b4c076cc11d0ee125833a13ff21b1acf9c06a 100644 (file)
@@ -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
index 4130b2497292ecb2486122fa35f3fb8b7be67722..2952f217c3200099f672dfb55603f61d04809fd5 100644 (file)
@@ -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) {