summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/gdm-common.c26
-rw-r--r--common/gdm-common.h2
-rw-r--r--configure.ac28
-rw-r--r--daemon/Makefile.am5
-rw-r--r--daemon/gdm-session-worker.c56
-rw-r--r--daemon/gdm-slave-proxy.c44
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,