diff options
-rw-r--r-- | common/gdm-common.c | 26 | ||||
-rw-r--r-- | common/gdm-common.h | 2 | ||||
-rw-r--r-- | configure.ac | 28 | ||||
-rw-r--r-- | daemon/Makefile.am | 5 | ||||
-rw-r--r-- | daemon/gdm-session-worker.c | 56 | ||||
-rw-r--r-- | daemon/gdm-slave-proxy.c | 44 |
6 files changed, 147 insertions, 14 deletions
diff --git a/common/gdm-common.c b/common/gdm-common.c index faab0d7a..ae6129c2 100644 --- a/common/gdm-common.c +++ b/common/gdm-common.c @@ -66,6 +66,32 @@ gdm_is_version_unstable (void) } gboolean +gdm_clear_close_on_exec_flag (int fd) +{ + int flags; + + if (fd < 0) { + return FALSE; + } + + flags = fcntl (fd, F_GETFD, 0); + + if (flags < 0) { + return FALSE; + } + + if ((flags & FD_CLOEXEC) != 0) { + int status; + + status = fcntl (fd, F_SETFD, flags & ~FD_CLOEXEC); + + return status != -1; + } + + return TRUE; +} + +gboolean gdm_get_pwent_for_name (const char *name, struct passwd **pwentp) { diff --git a/common/gdm-common.h b/common/gdm-common.h index 61d2dd30..00012743 100644 --- a/common/gdm-common.h +++ b/common/gdm-common.h @@ -45,6 +45,8 @@ int gdm_signal_pid (int pid, gboolean gdm_get_pwent_for_name (const char *name, struct passwd **pwentp); +gboolean gdm_clear_close_on_exec_flag (int fd); + const char * gdm_make_temp_dir (char *template); gboolean gdm_string_hex_encode (const GString *source, diff --git a/configure.ac b/configure.ac index 59121346..8ce4533e 100644 --- a/configure.ac +++ b/configure.ac @@ -283,6 +283,10 @@ AC_ARG_WITH([systemdsystemunitdir], AS_HELP_STRING([--with-systemdsystemunitdir=DIR], [Directory for systemd service files]), [with_systemdsystemunitdir=$withval], [with_systemdsystemunitdir=$($PKG_CONFIG --variable=systemdsystemunitdir systemd)]) +AC_ARG_ENABLE(systemd-journal, + AS_HELP_STRING([--enable-systemd-journal], + [Add journald support @<:@default=auto@:>@]), + [enable_systemd_journal=$enableval], [enable_systemd_journal=auto]) AC_ARG_WITH(plymouth, AS_HELP_STRING([--with-plymouth], [Add plymouth support @<:@default=auto@:>@]), @@ -945,6 +949,30 @@ fi AC_SUBST(SYSTEMD_CFLAGS) AC_SUBST(SYSTEMD_LIBS) +PKG_CHECK_MODULES(JOURNALD, + [libsystemd-journal], + [have_journald=yes], [have_journald=no]) + +if test "x$enable_systemd_journal" = "xauto" ; then + if test x$have_journald = xno ; then + use_journald=no + else + use_journald=yes + fi +else + use_journald="$enable_systemd_journal" +fi + +if test "x$use_journald" != "xno" ; then + if test "x$have_journald" = "xno"; then + AC_MSG_ERROR([journald support explicitly required, but journald not found]) + fi + + AC_DEFINE(ENABLE_SYSTEMD_JOURNAL, 1, [Define to enable systemd journal support]) +fi +AC_SUBST(JOURNALD_CFLAGS) +AC_SUBST(JOURNALD_LIBS) + AC_PATH_PROG(SYSTEMD_X_SERVER, systemd-multi-seat-x, [/lib/systemd/systemd-multi-seat-x], [/lib/systemd:/usr/lib/systemd:$PATH]) AC_SUBST(SYSTEMD_X_SERVER) AC_DEFINE_UNQUOTED(SYSTEMD_X_SERVER,"$SYSTEMD_X_SERVER",[Path to systemd X server wrapper]) diff --git a/daemon/Makefile.am b/daemon/Makefile.am index bb84765c..582ff767 100644 --- a/daemon/Makefile.am +++ b/daemon/Makefile.am @@ -27,6 +27,7 @@ AM_CPPFLAGS = \ $(WARN_CFLAGS) \ $(DEBUG_CFLAGS) \ $(SYSTEMD_CFLAGS) \ + $(JOURNALD_CFLAGS) \ $(LIBSELINUX_CFLAGS) \ -DLANG_CONFIG_FILE=\"$(LANG_CONFIG_FILE)\" \ $(NULL) @@ -198,6 +199,7 @@ gdm_simple_slave_LDADD = \ $(DAEMON_LIBS) \ $(EXTRA_DAEMON_LIBS) \ $(SYSTEMD_LIBS) \ + $(JOURNALD_LIBS) \ $(NULL) gdm_xdmcp_chooser_slave_SOURCES = \ @@ -242,6 +244,7 @@ gdm_xdmcp_chooser_slave_LDADD = \ $(DAEMON_LIBS) \ $(EXTRA_DAEMON_LIBS) \ $(SYSTEMD_LIBS) \ + $(JOURNALD_LIBS) \ $(top_builddir)/common/libgdmcommon.la \ $(NULL) @@ -292,6 +295,7 @@ gdm_session_worker_LDADD = \ $(top_builddir)/common/libgdmcommon.la \ $(DAEMON_LIBS) \ $(SYSTEMD_LIBS) \ + $(JOURNALD_LIBS) \ $(LIBSELINUX_LIBS) \ $(NULL) @@ -383,6 +387,7 @@ gdm_binary_LDADD = \ $(XDMCP_LIBS) \ $(LIBWRAP_LIBS) \ $(SYSTEMD_LIBS) \ + $(JOURNALD_LIBS) \ $(NULL) if WITH_CONSOLE_KIT diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c index 57e49a4f..ab84182b 100644 --- a/daemon/gdm-session-worker.c +++ b/daemon/gdm-session-worker.c @@ -50,6 +50,10 @@ #include <systemd/sd-daemon.h> #endif +#ifdef ENABLE_SYSTEMD_JOURNAL +#include <systemd/sd-journal.h> +#endif + #ifdef HAVE_SELINUX #include <selinux/selinux.h> #endif /* HAVE_SELINUX */ @@ -1786,14 +1790,19 @@ gdm_session_worker_start_session (GdmSessionWorker *worker, const char * const * environment; char *kerberos_cache; char *home_dir; - int fd; + int stdin_fd = -1, stdout_fd = -1, stderr_fd = -1; + gboolean has_journald = FALSE; - fd = open ("/dev/null", O_RDWR); - dup2 (fd, STDIN_FILENO); - close (fd); + stdin_fd = open ("/dev/null", O_RDWR); + dup2 (stdin_fd, STDIN_FILENO); + close (stdin_fd); - if (worker->priv->is_program_session) { - fd = _open_program_session_log (worker->priv->log_file); +#ifdef ENABLE_SYSTEMD_JOURNAL + has_journald = sd_booted() > 0; +#endif + if (!has_journald && worker->priv->is_program_session) { + stdout_fd = _open_program_session_log (worker->priv->log_file); + stderr_fd = dup (stdout_fd); } #ifdef HAVE_LOGINCAP @@ -1846,7 +1855,19 @@ gdm_session_worker_start_session (GdmSessionWorker *worker, g_chdir ("/"); } - if (!worker->priv->is_program_session) { +#ifdef ENABLE_SYSTEMD_JOURNAL + if (has_journald) { + stdout_fd = sd_journal_stream_fd (worker->priv->arguments[0], LOG_INFO, FALSE); + stderr_fd = sd_journal_stream_fd (worker->priv->arguments[0], LOG_WARNING, FALSE); + + /* Unset the CLOEXEC flags, because sd_journal_stream_fd + * gives it to us by default. + */ + gdm_clear_close_on_exec_flag (stdout_fd); + gdm_clear_close_on_exec_flag (stderr_fd); + } +#endif + if (!has_journald && !worker->priv->is_program_session) { if (home_dir != NULL && home_dir[0] != '\0') { char *cache_dir; char *log_dir; @@ -1860,20 +1881,29 @@ gdm_session_worker_start_session (GdmSessionWorker *worker, g_free (cache_dir); if (g_mkdir_with_parents (log_dir, S_IRWXU) == 0) { - fd = _open_user_session_log (log_dir); + stdout_fd = _open_user_session_log (log_dir); + stderr_fd = dup (stdout_fd); } else { - fd = open ("/dev/null", O_RDWR); + stdout_fd = open ("/dev/null", O_RDWR); + stderr_fd = dup (stdout_fd); } g_free (log_dir); } else { - fd = open ("/dev/null", O_RDWR); + stdout_fd = open ("/dev/null", O_RDWR); + stderr_fd = dup (stdout_fd); } } g_free (home_dir); - dup2 (fd, STDOUT_FILENO); - dup2 (fd, STDERR_FILENO); - close (fd); + if (stdout_fd != -1) { + dup2 (stdout_fd, STDOUT_FILENO); + close (stdout_fd); + } + + if (stderr_fd != -1) { + dup2 (stderr_fd, STDERR_FILENO); + close (stderr_fd); + } gdm_log_shutdown (); diff --git a/daemon/gdm-slave-proxy.c b/daemon/gdm-slave-proxy.c index 8a91fba8..76d992bd 100644 --- a/daemon/gdm-slave-proxy.c +++ b/daemon/gdm-slave-proxy.c @@ -30,6 +30,14 @@ #include <errno.h> #include <signal.h> +#ifdef WITH_SYSTEMD +#include <systemd/sd-daemon.h> +#endif + +#ifdef ENABLE_SYSTEMD_JOURNAL +#include <systemd/sd-journal.h> +#endif + #include <glib.h> #include <glib/gi18n.h> #include <glib/gstdio.h> @@ -126,12 +134,33 @@ rotate_logs (const char *path, } typedef struct { + const char *identifier; const char *log_file; } SpawnChildData; static void spawn_child_setup (SpawnChildData *data) { +#ifdef ENABLE_SYSTEMD_JOURNAL + if (sd_booted () > 0) { + int stdout_fd, stderr_fd; + + stdout_fd = sd_journal_stream_fd (data->identifier, LOG_INFO, FALSE); + stderr_fd = sd_journal_stream_fd (data->identifier, LOG_WARNING, FALSE); + + gdm_clear_close_on_exec_flag (stdout_fd); + gdm_clear_close_on_exec_flag (stderr_fd); + + if (stdout_fd != -1) { + VE_IGNORE_EINTR (dup2 (stdout_fd, STDOUT_FILENO)); + } + + if (stderr_fd != -1) { + VE_IGNORE_EINTR (dup2 (stderr_fd, STDERR_FILENO)); + } + return; + } +#endif if (data->log_file != NULL) { int logfd; @@ -161,6 +190,7 @@ spawn_command_line_async (const char *command_line, gboolean ret; gboolean res; SpawnChildData data; + gboolean has_journald = FALSE; ret = FALSE; @@ -172,7 +202,19 @@ spawn_command_line_async (const char *command_line, goto out; } - data.log_file = log_file; + data.identifier = argv[0]; + +#ifdef ENABLE_SYSTEMD_JOURNAL + if (sd_booted () > 0) { + has_journald = TRUE; + } +#endif + + if (has_journald) { + data.log_file = NULL; + } else { + data.log_file = log_file; + } local_error = NULL; res = g_spawn_async (NULL, |