From 9f307439352d97d086e0d62dcf7716d0a78e86c1 Mon Sep 17 00:00:00 2001 From: Chengwei Yang Date: Mon, 9 Sep 2013 13:23:02 +0800 Subject: [PATCH 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 6200d21..4ba436b 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); @@ -1223,7 +1230,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) @@ -1263,6 +1275,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, @@ -1271,6 +1289,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()"); } @@ -1280,6 +1302,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; @@ -1309,6 +1335,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