Commit a505c58c authored by Colin Walters's avatar Colin Walters Committed by Ray Strode
Browse files

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
parent 4952f6e5
......@@ -65,6 +65,32 @@ gdm_is_version_unstable (void)
return unstable;
}
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)
......
......@@ -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,
......
......@@ -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])
......
......@@ -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
......
......@@ -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 ();
......
......@@ -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,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment