From 2b537f23bb0dcef84d1ac71254f7dcba9e0a7260 Mon Sep 17 00:00:00 2001 From: Chengwei Yang Date: Fri, 13 Sep 2013 21:37:19 +0800 Subject: [PATCH v3 2/3] Handle activated child stdout/stderr correctly in systemd environment In systemd environment, dbus-daemon will run as no-fork mode since this is the recommended practice of systemd. In that scenario, child activated by dbus-daemon will inherit dbus-daemon standard streams, includes stdin/stdout/stderr. stdin will be redirected to /dev/null by systemd and stdout/stderr will be catched by systemd log subsystem. Since the child inherit stdout/stderr from dbus-daemon, so from systemd journal log, the child log output will be identified with dbus-daemon identifier. So it's a little confusing. This patch redirects the child stdout/stderr to systemd journal stream, and with its owned service name as identifier. However, thing not fixed perfectly due to the socket ucred of the child is owned by dbus-daemon, so the pid isn't the real pid of the chile. Bug: https://bugs.freedesktop.org/show_bug.cgi?id=68559 --- configure.ac | 2 +- dbus/dbus-spawn.c | 32 +++++++++++++++++++++++++++++++- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index ab7b1e1..4168b8f 100644 --- a/configure.ac +++ b/configure.ac @@ -1173,7 +1173,7 @@ if test x$enable_systemd = xno ; then have_systemd=no; else PKG_CHECK_MODULES(SYSTEMD, - [libsystemd-login >= 32, libsystemd-daemon >= 32], + [libsystemd-login >= 32, libsystemd-daemon >= 32, libsystemd-journal >= 32], have_systemd=yes, have_systemd=no) fi diff --git a/dbus/dbus-spawn.c b/dbus/dbus-spawn.c index e7889b6..8c0a764 100644 --- a/dbus/dbus-spawn.c +++ b/dbus/dbus-spawn.c @@ -38,6 +38,9 @@ #ifdef HAVE_ERRNO_H #include #endif +#ifdef HAVE_SYSTEMD +#include +#endif extern char **environ; @@ -1147,6 +1150,10 @@ _dbus_spawn_async_with_babysitter (DBusBabysitter **sitter_p, int child_err_report_pipe[2] = { -1, -1 }; int babysitter_pipe[2] = { -1, -1 }; pid_t pid; +#ifdef HAVE_SYSTEMD + int fd_out = -1; + int fd_err = -1; +#endif _DBUS_ASSERT_ERROR_IS_CLEAR (error); @@ -1233,7 +1240,12 @@ _dbus_spawn_async_with_babysitter (DBusBabysitter **sitter_p, } _DBUS_ASSERT_ERROR_IS_CLEAR (error); - + +#ifdef HAVE_SYSTEMD + fd_out = sd_journal_stream_fd (sitter->executable, LOG_INFO, FALSE); + fd_err = sd_journal_stream_fd (sitter->executable, LOG_WARNING, FALSE); +#endif + pid = fork (); if (pid < 0) @@ -1273,6 +1285,12 @@ _dbus_spawn_async_with_babysitter (DBusBabysitter **sitter_p, */ signal (SIGPIPE, SIG_IGN); +#ifdef HAVE_SYSTEMD + dup2 (fd_out, STDOUT_FILENO); + dup2 (fd_err, STDERR_FILENO); + close_and_invalidate (&fd_out); + close_and_invalidate (&fd_err); +#endif do_exec (child_err_report_pipe[WRITE_END], argv, env, @@ -1281,6 +1299,10 @@ _dbus_spawn_async_with_babysitter (DBusBabysitter **sitter_p, } else { +#ifdef HAVE_SYSTEMD + close_and_invalidate (&fd_out); + close_and_invalidate (&fd_err); +#endif babysit (grandchild_pid, babysitter_pipe[1]); _dbus_assert_not_reached ("Got to code after babysit()"); } @@ -1290,6 +1312,10 @@ _dbus_spawn_async_with_babysitter (DBusBabysitter **sitter_p, /* Close the uncared-about ends of the pipes */ close_and_invalidate (&child_err_report_pipe[WRITE_END]); close_and_invalidate (&babysitter_pipe[1]); +#ifdef HAVE_SYSTEMD + close_and_invalidate (&fd_out); + close_and_invalidate (&fd_err); +#endif sitter->socket_to_babysitter = babysitter_pipe[0]; babysitter_pipe[0] = -1; @@ -1319,6 +1345,10 @@ _dbus_spawn_async_with_babysitter (DBusBabysitter **sitter_p, close_and_invalidate (&child_err_report_pipe[WRITE_END]); close_and_invalidate (&babysitter_pipe[0]); close_and_invalidate (&babysitter_pipe[1]); +#ifdef HAVE_SYSTEMD + close_and_invalidate (&fd_out); + close_and_invalidate (&fd_err); +#endif if (sitter != NULL) _dbus_babysitter_unref (sitter); -- 1.7.9.5