]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core: Settle log target if we're going to be closing all fds
authorDaan De Meyer <daan.j.demeyer@gmail.com>
Mon, 20 Mar 2023 12:26:57 +0000 (13:26 +0100)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Wed, 22 Mar 2023 12:20:08 +0000 (13:20 +0100)
Whenever we're going to close all file descriptors, we tend to close
the log and set it into open when needed mode. When this is done with
the logging target set to LOG_TARGET_AUTO, we run into issues because
for every logging call, we'll check if stderr is connected to the
journal to determine where to send the logging message. This check
obviously stops working when we close stderr, so we settle the log
target before we do that so that we keep using the same logging
target even after stderr is closed.

src/activate/activate.c
src/basic/log.c
src/basic/log.h
src/basic/process-util.c
src/core/execute.c
src/nspawn/nspawn.c
src/test/test-fd-util.c

index ea141c54bdf65ee48d6ae29d63aacea645402624..4a639703260764c219c14a590895ecff1c2b9f8f 100644 (file)
@@ -81,6 +81,7 @@ static int open_sockets(int *ret_epoll_fd, bool accept) {
 
                 log_close();
                 log_set_open_when_needed(true);
+                log_settle_target();
 
                 r = close_all_fds(except, n);
                 if (r < 0)
index 8b973f9e0a905502529aa63c01c7f249f1f89196..21c6f2a685a89ff0fa2a64767f945417ee321b7c 100644 (file)
@@ -1264,6 +1264,24 @@ LogTarget log_get_target(void) {
         return log_target;
 }
 
+void log_settle_target(void) {
+
+        /* If we're using LOG_TARGET_AUTO and opening the log again on every single log call, we'll check if
+         * stderr is attached to the journal every single log call. However, if we then close all file
+         * descriptors later, that will stop working because stderr will be closed as well. To avoid that
+         * problem, this function is used to permanently change the log target depending on whether stderr is
+         * connected to the journal or not. */
+
+        LogTarget t = log_get_target();
+
+        if (t != LOG_TARGET_AUTO)
+                return;
+
+        t = getpid_cached() == 1 || stderr_is_journal() ? (prohibit_ipc ? LOG_TARGET_KMSG : LOG_TARGET_JOURNAL_OR_KMSG)
+                                                        : LOG_TARGET_CONSOLE;
+        log_set_target(t);
+}
+
 int log_get_max_level(void) {
         return log_max_level;
 }
index c4ac73e27bcd5e2d2a2609cce5e132809d48e13f..226402522cbb1a0310ad382ae907bbd780ab7a97 100644 (file)
@@ -54,6 +54,7 @@ void log_set_target(LogTarget target);
 void log_set_target_and_open(LogTarget target);
 int log_set_target_from_string(const char *e);
 LogTarget log_get_target(void) _pure_;
+void log_settle_target(void);
 
 void log_set_max_level(int level);
 int log_set_max_level_from_string(const char *e);
index 5d499a57b4f015db0ac14c01647109cb6b177f96..2fc2f924509ed4dc25161ab4d4724cb7bea957c9 100644 (file)
@@ -1223,6 +1223,7 @@ int safe_fork_full(
                 /* Close the logs if requested, before we log anything. And make sure we reopen it if needed. */
                 log_close();
                 log_set_open_when_needed(true);
+                log_settle_target();
         }
 
         if (name) {
index 3f85b5f3cd6e54659589b667ba7b0dec7ce3a869..1532833c315df8fc3e5fa9252f6cdd90da5bc6d9 100644 (file)
@@ -4488,6 +4488,7 @@ static int exec_child(
 
         log_forget_fds();
         log_set_open_when_needed(true);
+        log_settle_target();
 
         /* In case anything used libc syslog(), close this here, too */
         closelog();
index 056fad005d3e97caf992fd011d77e03b4ba4902c..f872b2e8f6b01f410dcb6787aee80ff18ba2b861 100644 (file)
@@ -3551,6 +3551,7 @@ static int inner_child(
          * it again. Note that the other fds closed here are at least the locking and barrier fds. */
         log_close();
         log_set_open_when_needed(true);
+        log_settle_target();
 
         (void) fdset_close_others(fds);
 
index 1f14f0b6cb4b85d78e7a758eba1cfd5314b6a069..148694e0295454ee740939e5cec329cf7bbe6fad 100644 (file)
@@ -278,6 +278,7 @@ static void test_close_all_fds_inner(void) {
         /* Close logging fd first, so that we don't confuse it by closing its fd */
         log_close();
         log_set_open_when_needed(true);
+        log_settle_target();
 
         /* Close all but the ones to keep */
         assert_se(close_all_fds(keep, n_keep) >= 0);