[gdm] Log output to systemd journal if available



commit a505c58cee7c1d4f397fb8c0903cc78221c308b4
Author: Colin Walters <walters verbum org>
Date:   Fri Jan 18 16:07:20 2013 -0500

    Log output to systemd journal if available
    
    Previously, we put stuff in /var/log/gdm for the session, and
    then ~/.cache/gdm/session.log for the user.
    
    Now let's use explicit sd_journal_stream_fd() calls.
    
    Some adjustments from Ray Strode.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=676181

 common/gdm-common.c         |   26 ++++++++++++++++++++
 common/gdm-common.h         |    2 +
 configure.ac                |   28 +++++++++++++++++++++
 daemon/Makefile.am          |    5 ++++
 daemon/gdm-session-worker.c |   56 +++++++++++++++++++++++++++++++++----------
 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 faab0d7..ae6129c 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 61d2dd3..0001274 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 5912134..8ce4533 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 bb84765..582ff76 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 57e49a4..ab84182 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 8a91fba..76d992b 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,



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]