guibuilder_pel7x64builder0
6 years ago
11 changed files with 1880 additions and 6619 deletions
@ -0,0 +1,136 @@ |
|||||||
|
From 086d68f24d984fb48e44aa16aa815825cd5ed0bc Mon Sep 17 00:00:00 2001 |
||||||
|
From: Jason Pleau <jason@jpleau.ca> |
||||||
|
Date: Wed, 30 May 2018 21:48:22 -0400 |
||||||
|
Subject: [PATCH] daemon/gdm-session-record.c: open/close the utmp database |
||||||
|
|
||||||
|
pututxline() was used without first opening the utxmp database and |
||||||
|
without closing it, preventing the logout entry from being fully |
||||||
|
committed. |
||||||
|
|
||||||
|
This caused the number of logged-in users to increment after each login, |
||||||
|
as logging out did not correctly remove the user login record from utmp. |
||||||
|
|
||||||
|
This commit wraps pututxline() between setutxent() and endutxent(), |
||||||
|
making sure that the login/logout operation are fully flushed. |
||||||
|
|
||||||
|
Fixes #381 |
||||||
|
--- |
||||||
|
daemon/gdm-session-record.c | 4 ++++ |
||||||
|
1 file changed, 4 insertions(+) |
||||||
|
|
||||||
|
diff --git a/daemon/gdm-session-record.c b/daemon/gdm-session-record.c |
||||||
|
index 487f10047..d2df58873 100644 |
||||||
|
--- a/daemon/gdm-session-record.c |
||||||
|
+++ b/daemon/gdm-session-record.c |
||||||
|
@@ -186,104 +186,108 @@ gdm_session_record_login (GPid session_pid, |
||||||
|
|
||||||
|
g_debug ("Writing login record"); |
||||||
|
|
||||||
|
#if defined(HAVE_UT_UT_TYPE) |
||||||
|
session_record.ut_type = USER_PROCESS; |
||||||
|
g_debug ("using ut_type USER_PROCESS"); |
||||||
|
#endif |
||||||
|
|
||||||
|
record_set_timestamp (&session_record); |
||||||
|
record_set_pid (&session_record, session_pid); |
||||||
|
record_set_host (&session_record, x11_display_name, host_name); |
||||||
|
record_set_line (&session_record, display_device, x11_display_name); |
||||||
|
|
||||||
|
/* Handle wtmp */ |
||||||
|
g_debug ("Writing wtmp session record to " GDM_NEW_SESSION_RECORDS_FILE); |
||||||
|
#if defined(HAVE_UPDWTMPX) |
||||||
|
updwtmpx (GDM_NEW_SESSION_RECORDS_FILE, &session_record); |
||||||
|
#elif defined(HAVE_UPDWTMP) |
||||||
|
updwtmp (GDM_NEW_SESSION_RECORDS_FILE, &session_record); |
||||||
|
#elif defined(HAVE_LOGWTMP) && defined(HAVE_UT_UT_HOST) |
||||||
|
#if defined(HAVE_UT_UT_USER) |
||||||
|
logwtmp (session_record.ut_line, session_record.ut_user, session_record.ut_host); |
||||||
|
#elif defined(HAVE_UT_UT_NAME) |
||||||
|
logwtmp (session_record.ut_line, session_record.ut_name, session_record.ut_host); |
||||||
|
#endif |
||||||
|
#endif |
||||||
|
|
||||||
|
/* Handle utmp */ |
||||||
|
#if defined(HAVE_GETUTXENT) |
||||||
|
g_debug ("Adding or updating utmp record for login"); |
||||||
|
+ setutxent(); |
||||||
|
pututxline (&session_record); |
||||||
|
+ endutxent(); |
||||||
|
#elif defined(HAVE_LOGIN) |
||||||
|
login (&session_record); |
||||||
|
#endif |
||||||
|
} |
||||||
|
|
||||||
|
void |
||||||
|
gdm_session_record_logout (GPid session_pid, |
||||||
|
const char *user_name, |
||||||
|
const char *host_name, |
||||||
|
const char *x11_display_name, |
||||||
|
const char *display_device) |
||||||
|
{ |
||||||
|
UTMP session_record = { 0 }; |
||||||
|
|
||||||
|
if (x11_display_name == NULL) |
||||||
|
x11_display_name = display_device; |
||||||
|
|
||||||
|
g_debug ("Writing logout record"); |
||||||
|
|
||||||
|
#if defined(HAVE_UT_UT_TYPE) |
||||||
|
session_record.ut_type = DEAD_PROCESS; |
||||||
|
g_debug ("using ut_type DEAD_PROCESS"); |
||||||
|
#endif |
||||||
|
|
||||||
|
record_set_timestamp (&session_record); |
||||||
|
record_set_pid (&session_record, session_pid); |
||||||
|
record_set_host (&session_record, x11_display_name, host_name); |
||||||
|
record_set_line (&session_record, display_device, x11_display_name); |
||||||
|
|
||||||
|
/* Handle wtmp */ |
||||||
|
g_debug ("Writing wtmp logout record to " GDM_NEW_SESSION_RECORDS_FILE); |
||||||
|
#if defined(HAVE_UPDWTMPX) |
||||||
|
updwtmpx (GDM_NEW_SESSION_RECORDS_FILE, &session_record); |
||||||
|
#elif defined (HAVE_UPDWTMP) |
||||||
|
updwtmp (GDM_NEW_SESSION_RECORDS_FILE, &session_record); |
||||||
|
#elif defined(HAVE_LOGWTMP) |
||||||
|
logwtmp (session_record.ut_line, "", ""); |
||||||
|
#endif |
||||||
|
|
||||||
|
/* Handle utmp */ |
||||||
|
#if defined(HAVE_GETUTXENT) |
||||||
|
g_debug ("Adding or updating utmp record for logout"); |
||||||
|
+ setutxent(); |
||||||
|
pututxline (&session_record); |
||||||
|
+ endutxent(); |
||||||
|
#elif defined(HAVE_LOGOUT) |
||||||
|
logout (session_record.ut_line); |
||||||
|
#endif |
||||||
|
} |
||||||
|
|
||||||
|
void |
||||||
|
gdm_session_record_failed (GPid session_pid, |
||||||
|
const char *user_name, |
||||||
|
const char *host_name, |
||||||
|
const char *x11_display_name, |
||||||
|
const char *display_device) |
||||||
|
{ |
||||||
|
UTMP session_record = { 0 }; |
||||||
|
|
||||||
|
if (x11_display_name == NULL) |
||||||
|
x11_display_name = display_device; |
||||||
|
|
||||||
|
record_set_username (&session_record, user_name); |
||||||
|
|
||||||
|
g_debug ("Writing failed session attempt record"); |
||||||
|
|
||||||
|
#if defined(HAVE_UT_UT_TYPE) |
||||||
|
session_record.ut_type = USER_PROCESS; |
||||||
|
g_debug ("using ut_type USER_PROCESS"); |
||||||
|
#endif |
||||||
|
|
||||||
|
record_set_timestamp (&session_record); |
||||||
|
record_set_pid (&session_record, session_pid); |
||||||
|
record_set_host (&session_record, x11_display_name, host_name); |
||||||
|
record_set_line (&session_record, display_device, x11_display_name); |
||||||
|
-- |
||||||
|
2.17.1 |
||||||
|
|
@ -0,0 +1,112 @@ |
|||||||
|
From a9b82ca4a87315235924317c0fc48324a8b7cb9f Mon Sep 17 00:00:00 2001 |
||||||
|
From: Ray Strode <rstrode@redhat.com> |
||||||
|
Date: Mon, 21 May 2018 11:13:31 -0400 |
||||||
|
Subject: [PATCH] data: change cirrus blacklist to use gdm-disable-wayland |
||||||
|
|
||||||
|
Now that we have a gdm-disable-wayland binary for disabling |
||||||
|
wayland at boot, we should use it. |
||||||
|
|
||||||
|
This commit changes the cirrus udev rule to use gdm-disable-wayland, |
||||||
|
rather than running sh and printf. |
||||||
|
|
||||||
|
https://bugzilla.gnome.org/show_bug.cgi?id=796315 |
||||||
|
|
||||||
|
|
||||||
|
(cherry picked from commit a913eea70342411247e770a91b75dd800941bb6e) |
||||||
|
--- |
||||||
|
data/61-gdm.rules | 2 -- |
||||||
|
data/61-gdm.rules.in | 2 ++ |
||||||
|
data/Makefile.am | 5 +++++ |
||||||
|
3 files changed, 7 insertions(+), 2 deletions(-) |
||||||
|
delete mode 100644 data/61-gdm.rules |
||||||
|
create mode 100644 data/61-gdm.rules.in |
||||||
|
|
||||||
|
diff --git a/data/61-gdm.rules b/data/61-gdm.rules |
||||||
|
deleted file mode 100644 |
||||||
|
index 5ffa8b8a0..000000000 |
||||||
|
--- a/data/61-gdm.rules |
||||||
|
+++ /dev/null |
||||||
|
@@ -1,2 +0,0 @@ |
||||||
|
-# disable Wayland on Cirrus chipsets |
||||||
|
-ATTR{vendor}=="0x1013", ATTR{device}=="0x00b8", ATTR{subsystem_vendor}=="0x1af4", ATTR{subsystem_device}=="0x1100", RUN+="/bin/sh -c '/bin/mkdir /run/gdm ; /usr/bin/printf \"[daemon]\nWaylandEnable=false\" >> /run/gdm/custom.conf'" |
||||||
|
diff --git a/data/61-gdm.rules.in b/data/61-gdm.rules.in |
||||||
|
new file mode 100644 |
||||||
|
index 000000000..de8e17903 |
||||||
|
--- /dev/null |
||||||
|
+++ b/data/61-gdm.rules.in |
||||||
|
@@ -0,0 +1,2 @@ |
||||||
|
+# disable Wayland on Cirrus chipsets |
||||||
|
+ATTR{vendor}=="0x1013", ATTR{device}=="0x00b8", ATTR{subsystem_vendor}=="0x1af4", ATTR{subsystem_device}=="0x1100", RUN+="@libexecdir@/gdm-disable-wayland" |
||||||
|
diff --git a/data/Makefile.am b/data/Makefile.am |
||||||
|
index a47e7900f..192dfa052 100644 |
||||||
|
--- a/data/Makefile.am |
||||||
|
+++ b/data/Makefile.am |
||||||
|
@@ -134,60 +134,65 @@ pam_lfs_files = \ |
||||||
|
EXTRA_DIST += $(pam_lfs_files) |
||||||
|
|
||||||
|
pam_arch_files = pam-arch/gdm-autologin.pam \ |
||||||
|
pam-arch/gdm-launch-environment.pam \ |
||||||
|
pam-arch/gdm-fingerprint.pam \ |
||||||
|
pam-arch/gdm-smartcard.pam \ |
||||||
|
pam-arch/gdm-password.pam \ |
||||||
|
pam-arch/gdm-pin.pam \ |
||||||
|
$(NULL) |
||||||
|
EXTRA_DIST += $(pam_arch_files) |
||||||
|
|
||||||
|
if ENABLE_REDHAT_PAM_CONFIG |
||||||
|
pam_files = $(pam_redhat_files) |
||||||
|
endif |
||||||
|
if ENABLE_OPENEMBEDDED_PAM_CONFIG |
||||||
|
pam_files = $(pam_openembedded_files) |
||||||
|
endif |
||||||
|
if ENABLE_EXHERBO_PAM_CONFIG |
||||||
|
pam_files = $(pam_exherbo_files) |
||||||
|
endif |
||||||
|
if ENABLE_LFS_PAM_CONFIG |
||||||
|
pam_files = $(pam_lfs_files) |
||||||
|
endif |
||||||
|
if ENABLE_ARCH_PAM_CONFIG |
||||||
|
pam_files = $(pam_arch_files) |
||||||
|
endif |
||||||
|
|
||||||
|
udevrulesdir = $(prefix)/lib/udev/rules.d |
||||||
|
udevrules_DATA = 61-gdm.rules |
||||||
|
|
||||||
|
+EXTRA_DIST += $(srcdir)/61-gdm.rules.in |
||||||
|
+61-gdm.rules: $(srcdir)/61-gdm.rules.in |
||||||
|
+ sed -e 's,[@]libexecdir[@],$(libexecdir),g' \ |
||||||
|
+ < $< > $@.tmp && mv $@.tmp $@ |
||||||
|
+ |
||||||
|
EXTRA_DIST += \ |
||||||
|
$(dconf_db_files) \ |
||||||
|
$(schemas_in_files) \ |
||||||
|
$(schemas_DATA) \ |
||||||
|
$(dbusconf_in_files) \ |
||||||
|
$(localealias_DATA) \ |
||||||
|
$(udevrules_DATA) \ |
||||||
|
gdm.schemas.in.in \ |
||||||
|
gdm.conf-custom.in \ |
||||||
|
Xsession.in \ |
||||||
|
Init.in \ |
||||||
|
PreSession.in \ |
||||||
|
PostSession.in \ |
||||||
|
PostLogin \ |
||||||
|
org.gnome.login-screen.gschema.xml.in \ |
||||||
|
$(NULL) |
||||||
|
|
||||||
|
CLEANFILES = \ |
||||||
|
Xsession \ |
||||||
|
gdm.conf-custom \ |
||||||
|
Init \ |
||||||
|
PreSession \ |
||||||
|
PostSession \ |
||||||
|
$(gsettings_SCHEMAS) \ |
||||||
|
greeter-dconf-defaults \ |
||||||
|
$(NULL) |
||||||
|
|
||||||
|
DISTCLEANFILES = \ |
||||||
|
$(dbusconf_DATA) \ |
||||||
|
gdm.schemas \ |
||||||
|
-- |
||||||
|
2.17.1 |
||||||
|
|
@ -0,0 +1,103 @@ |
|||||||
|
From 82006d15b70842d2b1ad7d47d9490e315436cb5f Mon Sep 17 00:00:00 2001 |
||||||
|
From: Ray Strode <rstrode@redhat.com> |
||||||
|
Date: Fri, 22 Jun 2018 14:44:11 -0400 |
||||||
|
Subject: [PATCH 1/6] manager: plug leak in maybe_activate_other_session |
||||||
|
|
||||||
|
The function asks logind what the currently active session is on the |
||||||
|
given seat. It then leaks the response. |
||||||
|
|
||||||
|
This commit plugs the leak. |
||||||
|
--- |
||||||
|
daemon/gdm-manager.c | 4 +++- |
||||||
|
1 file changed, 3 insertions(+), 1 deletion(-) |
||||||
|
|
||||||
|
diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c |
||||||
|
index 7539acf11..129cc0de4 100644 |
||||||
|
--- a/daemon/gdm-manager.c |
||||||
|
+++ b/daemon/gdm-manager.c |
||||||
|
@@ -1394,79 +1394,81 @@ get_login_window_session_id (const char *seat_id, |
||||||
|
out: |
||||||
|
if (sessions) { |
||||||
|
for (i = 0; sessions[i]; i ++) { |
||||||
|
free (sessions[i]); |
||||||
|
} |
||||||
|
|
||||||
|
free (sessions); |
||||||
|
} |
||||||
|
|
||||||
|
return ret; |
||||||
|
} |
||||||
|
|
||||||
|
static void |
||||||
|
activate_login_window_session_on_seat (GdmManager *self, |
||||||
|
const char *seat_id) |
||||||
|
{ |
||||||
|
char *session_id; |
||||||
|
|
||||||
|
if (!get_login_window_session_id (seat_id, &session_id)) { |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
activate_session_id (self, seat_id, session_id); |
||||||
|
} |
||||||
|
|
||||||
|
static void |
||||||
|
maybe_activate_other_session (GdmManager *self, |
||||||
|
GdmDisplay *old_display) |
||||||
|
{ |
||||||
|
char *seat_id = NULL; |
||||||
|
- char *session_id; |
||||||
|
+ char *session_id = NULL; |
||||||
|
int ret; |
||||||
|
|
||||||
|
g_object_get (G_OBJECT (old_display), |
||||||
|
"seat-id", &seat_id, |
||||||
|
NULL); |
||||||
|
|
||||||
|
ret = sd_seat_get_active (seat_id, &session_id, NULL); |
||||||
|
|
||||||
|
if (ret == 0) { |
||||||
|
GdmDisplay *display; |
||||||
|
|
||||||
|
display = gdm_display_store_find (self->priv->display_store, |
||||||
|
lookup_by_session_id, |
||||||
|
(gpointer) session_id); |
||||||
|
|
||||||
|
if (display == NULL) { |
||||||
|
activate_login_window_session_on_seat (self, seat_id); |
||||||
|
} |
||||||
|
+ |
||||||
|
+ g_free (session_id); |
||||||
|
} |
||||||
|
|
||||||
|
g_free (seat_id); |
||||||
|
} |
||||||
|
|
||||||
|
static const char * |
||||||
|
get_username_for_greeter_display (GdmManager *manager, |
||||||
|
GdmDisplay *display) |
||||||
|
{ |
||||||
|
gboolean doing_initial_setup = FALSE; |
||||||
|
|
||||||
|
g_object_get (G_OBJECT (display), |
||||||
|
"doing-initial-setup", &doing_initial_setup, |
||||||
|
NULL); |
||||||
|
|
||||||
|
if (doing_initial_setup) { |
||||||
|
return INITIAL_SETUP_USERNAME; |
||||||
|
} else { |
||||||
|
return GDM_USERNAME; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
static void |
||||||
|
set_up_automatic_login_session (GdmManager *manager, |
||||||
|
GdmDisplay *display) |
||||||
|
{ |
||||||
|
GdmSession *session; |
||||||
|
char *display_session_type = NULL; |
||||||
|
gboolean is_initial; |
||||||
|
|
||||||
|
-- |
||||||
|
2.19.0 |
||||||
|
|
@ -0,0 +1,92 @@ |
|||||||
|
From 6b4402fb0bbf17803c2354e92fc448a537d2d506 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Ray Strode <rstrode@redhat.com> |
||||||
|
Date: Fri, 22 Jun 2018 14:55:39 -0400 |
||||||
|
Subject: [PATCH 2/6] manager: start login screen if old one is finished |
||||||
|
|
||||||
|
Since commit 22c332ba we try to start a login screen if we end up |
||||||
|
on an empty VT and there isn't one running. |
||||||
|
|
||||||
|
Unfortunately the check for "is on an empty VT" is a little busted. |
||||||
|
It counts the VT has non-empty if there's a display associated with |
||||||
|
it, even if that display is in the FINISHED state about to be |
||||||
|
reaped. |
||||||
|
|
||||||
|
That means, in some cases, we'll still leave the user on an empty |
||||||
|
VT with no login screen. |
||||||
|
|
||||||
|
This commit addresses the problem by explicitly checking for |
||||||
|
FINISHED displays, and proceeding even in their presense. |
||||||
|
--- |
||||||
|
daemon/gdm-manager.c | 2 +- |
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-) |
||||||
|
|
||||||
|
diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c |
||||||
|
index 129cc0de4..3f5772e65 100644 |
||||||
|
--- a/daemon/gdm-manager.c |
||||||
|
+++ b/daemon/gdm-manager.c |
||||||
|
@@ -1410,61 +1410,61 @@ activate_login_window_session_on_seat (GdmManager *self, |
||||||
|
char *session_id; |
||||||
|
|
||||||
|
if (!get_login_window_session_id (seat_id, &session_id)) { |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
activate_session_id (self, seat_id, session_id); |
||||||
|
} |
||||||
|
|
||||||
|
static void |
||||||
|
maybe_activate_other_session (GdmManager *self, |
||||||
|
GdmDisplay *old_display) |
||||||
|
{ |
||||||
|
char *seat_id = NULL; |
||||||
|
char *session_id = NULL; |
||||||
|
int ret; |
||||||
|
|
||||||
|
g_object_get (G_OBJECT (old_display), |
||||||
|
"seat-id", &seat_id, |
||||||
|
NULL); |
||||||
|
|
||||||
|
ret = sd_seat_get_active (seat_id, &session_id, NULL); |
||||||
|
|
||||||
|
if (ret == 0) { |
||||||
|
GdmDisplay *display; |
||||||
|
|
||||||
|
display = gdm_display_store_find (self->priv->display_store, |
||||||
|
lookup_by_session_id, |
||||||
|
(gpointer) session_id); |
||||||
|
|
||||||
|
- if (display == NULL) { |
||||||
|
+ if (display == NULL || gdm_display_get_status (display) == GDM_DISPLAY_FINISHED) { |
||||||
|
activate_login_window_session_on_seat (self, seat_id); |
||||||
|
} |
||||||
|
|
||||||
|
g_free (session_id); |
||||||
|
} |
||||||
|
|
||||||
|
g_free (seat_id); |
||||||
|
} |
||||||
|
|
||||||
|
static const char * |
||||||
|
get_username_for_greeter_display (GdmManager *manager, |
||||||
|
GdmDisplay *display) |
||||||
|
{ |
||||||
|
gboolean doing_initial_setup = FALSE; |
||||||
|
|
||||||
|
g_object_get (G_OBJECT (display), |
||||||
|
"doing-initial-setup", &doing_initial_setup, |
||||||
|
NULL); |
||||||
|
|
||||||
|
if (doing_initial_setup) { |
||||||
|
return INITIAL_SETUP_USERNAME; |
||||||
|
} else { |
||||||
|
return GDM_USERNAME; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
static void |
||||||
|
set_up_automatic_login_session (GdmManager *manager, |
||||||
|
GdmDisplay *display) |
||||||
|
{ |
||||||
|
-- |
||||||
|
2.19.0 |
||||||
|
|
@ -0,0 +1,126 @@ |
|||||||
|
From 64779fcad9efa9fdb4b1a8963e2386cf763e53d8 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Ray Strode <rstrode@redhat.com> |
||||||
|
Date: Fri, 22 Jun 2018 15:26:03 -0400 |
||||||
|
Subject: [PATCH 3/6] manager: don't bail if session disappears out from under |
||||||
|
us |
||||||
|
|
||||||
|
It's entirely possible for a session returned by |
||||||
|
sd_seat_get_sessions to disappear immediately after the |
||||||
|
sd_seat_get_sessions call returns. This is especially |
||||||
|
likely at logout time where the session will briefly be |
||||||
|
in the "closing" state before getting reaped. |
||||||
|
|
||||||
|
If that happens when we're looking for a greeter session, we |
||||||
|
stop looking for a greeter session and bail out all confused. |
||||||
|
|
||||||
|
This commit fixes the confusion by gracefully handling the |
||||||
|
session disappearing by just proceeding to the next session |
||||||
|
in the list. |
||||||
|
--- |
||||||
|
daemon/gdm-manager.c | 9 +++++++++ |
||||||
|
1 file changed, 9 insertions(+) |
||||||
|
|
||||||
|
diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c |
||||||
|
index 3f5772e65..c391307fa 100644 |
||||||
|
--- a/daemon/gdm-manager.c |
||||||
|
+++ b/daemon/gdm-manager.c |
||||||
|
@@ -1318,87 +1318,96 @@ maybe_start_pending_initial_login (GdmManager *manager, |
||||||
|
g_free (user_session_seat_id); |
||||||
|
} |
||||||
|
|
||||||
|
static gboolean |
||||||
|
get_login_window_session_id (const char *seat_id, |
||||||
|
char **session_id) |
||||||
|
{ |
||||||
|
gboolean ret; |
||||||
|
int res, i; |
||||||
|
char **sessions; |
||||||
|
char *service_id; |
||||||
|
char *service_class; |
||||||
|
char *state; |
||||||
|
|
||||||
|
res = sd_seat_get_sessions (seat_id, &sessions, NULL, NULL); |
||||||
|
if (res < 0) { |
||||||
|
g_debug ("Failed to determine sessions: %s", strerror (-res)); |
||||||
|
return FALSE; |
||||||
|
} |
||||||
|
|
||||||
|
if (sessions == NULL || sessions[0] == NULL) { |
||||||
|
*session_id = NULL; |
||||||
|
ret = TRUE; |
||||||
|
goto out; |
||||||
|
} |
||||||
|
|
||||||
|
for (i = 0; sessions[i]; i ++) { |
||||||
|
|
||||||
|
res = sd_session_get_class (sessions[i], &service_class); |
||||||
|
if (res < 0) { |
||||||
|
+ if (res == -ENOENT || res == -ENXIO) { |
||||||
|
+ continue; |
||||||
|
+ } |
||||||
|
+ |
||||||
|
g_debug ("failed to determine class of session %s: %s", sessions[i], strerror (-res)); |
||||||
|
ret = FALSE; |
||||||
|
goto out; |
||||||
|
} |
||||||
|
|
||||||
|
if (strcmp (service_class, "greeter") != 0) { |
||||||
|
free (service_class); |
||||||
|
continue; |
||||||
|
} |
||||||
|
|
||||||
|
free (service_class); |
||||||
|
|
||||||
|
ret = sd_session_get_state (sessions[i], &state); |
||||||
|
if (ret < 0) { |
||||||
|
+ if (res == -ENOENT || res == -ENXIO) |
||||||
|
+ continue; |
||||||
|
+ |
||||||
|
g_debug ("failed to determine state of session %s: %s", sessions[i], strerror (-res)); |
||||||
|
ret = FALSE; |
||||||
|
goto out; |
||||||
|
} |
||||||
|
|
||||||
|
if (g_strcmp0 (state, "closing") == 0) { |
||||||
|
free (state); |
||||||
|
continue; |
||||||
|
} |
||||||
|
free (state); |
||||||
|
|
||||||
|
res = sd_session_get_service (sessions[i], &service_id); |
||||||
|
if (res < 0) { |
||||||
|
+ if (res == -ENOENT || res == -ENXIO) |
||||||
|
+ continue; |
||||||
|
g_debug ("failed to determine service of session %s: %s", sessions[i], strerror (-res)); |
||||||
|
ret = FALSE; |
||||||
|
goto out; |
||||||
|
} |
||||||
|
|
||||||
|
if (strcmp (service_id, "gdm-launch-environment") == 0) { |
||||||
|
*session_id = g_strdup (sessions[i]); |
||||||
|
ret = TRUE; |
||||||
|
|
||||||
|
free (service_id); |
||||||
|
goto out; |
||||||
|
} |
||||||
|
|
||||||
|
free (service_id); |
||||||
|
} |
||||||
|
|
||||||
|
*session_id = NULL; |
||||||
|
ret = TRUE; |
||||||
|
|
||||||
|
out: |
||||||
|
if (sessions) { |
||||||
|
for (i = 0; sessions[i]; i ++) { |
||||||
|
free (sessions[i]); |
||||||
|
} |
||||||
|
|
||||||
|
free (sessions); |
||||||
|
} |
||||||
|
|
||||||
|
return ret; |
||||||
|
} |
||||||
|
-- |
||||||
|
2.19.0 |
||||||
|
|
@ -0,0 +1,146 @@ |
|||||||
|
From 65c3fc674ee4ec0f5139973aa53114db2f1fcf45 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Ray Strode <rstrode@redhat.com> |
||||||
|
Date: Tue, 17 Jul 2018 15:40:25 -0400 |
||||||
|
Subject: [PATCH 4/6] manager: make get_login_window_session_id fail if no |
||||||
|
login screen |
||||||
|
|
||||||
|
Right now we oddly succeed from get_login_window_session_id |
||||||
|
if we can't find a login window. |
||||||
|
|
||||||
|
None of the caller expect that, so fail instead. |
||||||
|
--- |
||||||
|
daemon/gdm-manager.c | 4 ++-- |
||||||
|
1 file changed, 2 insertions(+), 2 deletions(-) |
||||||
|
|
||||||
|
diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c |
||||||
|
index c391307fa..34ee74033 100644 |
||||||
|
--- a/daemon/gdm-manager.c |
||||||
|
+++ b/daemon/gdm-manager.c |
||||||
|
@@ -1310,122 +1310,122 @@ maybe_start_pending_initial_login (GdmManager *manager, |
||||||
|
NULL); |
||||||
|
|
||||||
|
if (g_strcmp0 (greeter_seat_id, user_session_seat_id) == 0) { |
||||||
|
start_user_session (manager, operation); |
||||||
|
manager->priv->initial_login_operation = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
g_free (greeter_seat_id); |
||||||
|
g_free (user_session_seat_id); |
||||||
|
} |
||||||
|
|
||||||
|
static gboolean |
||||||
|
get_login_window_session_id (const char *seat_id, |
||||||
|
char **session_id) |
||||||
|
{ |
||||||
|
gboolean ret; |
||||||
|
int res, i; |
||||||
|
char **sessions; |
||||||
|
char *service_id; |
||||||
|
char *service_class; |
||||||
|
char *state; |
||||||
|
|
||||||
|
res = sd_seat_get_sessions (seat_id, &sessions, NULL, NULL); |
||||||
|
if (res < 0) { |
||||||
|
g_debug ("Failed to determine sessions: %s", strerror (-res)); |
||||||
|
return FALSE; |
||||||
|
} |
||||||
|
|
||||||
|
if (sessions == NULL || sessions[0] == NULL) { |
||||||
|
*session_id = NULL; |
||||||
|
- ret = TRUE; |
||||||
|
+ ret = FALSE; |
||||||
|
goto out; |
||||||
|
} |
||||||
|
|
||||||
|
for (i = 0; sessions[i]; i ++) { |
||||||
|
|
||||||
|
res = sd_session_get_class (sessions[i], &service_class); |
||||||
|
if (res < 0) { |
||||||
|
if (res == -ENOENT || res == -ENXIO) { |
||||||
|
continue; |
||||||
|
} |
||||||
|
|
||||||
|
g_debug ("failed to determine class of session %s: %s", sessions[i], strerror (-res)); |
||||||
|
ret = FALSE; |
||||||
|
goto out; |
||||||
|
} |
||||||
|
|
||||||
|
if (strcmp (service_class, "greeter") != 0) { |
||||||
|
free (service_class); |
||||||
|
continue; |
||||||
|
} |
||||||
|
|
||||||
|
free (service_class); |
||||||
|
|
||||||
|
ret = sd_session_get_state (sessions[i], &state); |
||||||
|
if (ret < 0) { |
||||||
|
if (res == -ENOENT || res == -ENXIO) |
||||||
|
continue; |
||||||
|
|
||||||
|
g_debug ("failed to determine state of session %s: %s", sessions[i], strerror (-res)); |
||||||
|
ret = FALSE; |
||||||
|
goto out; |
||||||
|
} |
||||||
|
|
||||||
|
if (g_strcmp0 (state, "closing") == 0) { |
||||||
|
free (state); |
||||||
|
continue; |
||||||
|
} |
||||||
|
free (state); |
||||||
|
|
||||||
|
res = sd_session_get_service (sessions[i], &service_id); |
||||||
|
if (res < 0) { |
||||||
|
if (res == -ENOENT || res == -ENXIO) |
||||||
|
continue; |
||||||
|
g_debug ("failed to determine service of session %s: %s", sessions[i], strerror (-res)); |
||||||
|
ret = FALSE; |
||||||
|
goto out; |
||||||
|
} |
||||||
|
|
||||||
|
if (strcmp (service_id, "gdm-launch-environment") == 0) { |
||||||
|
*session_id = g_strdup (sessions[i]); |
||||||
|
ret = TRUE; |
||||||
|
|
||||||
|
free (service_id); |
||||||
|
goto out; |
||||||
|
} |
||||||
|
|
||||||
|
free (service_id); |
||||||
|
} |
||||||
|
|
||||||
|
*session_id = NULL; |
||||||
|
- ret = TRUE; |
||||||
|
+ ret = FALSE; |
||||||
|
|
||||||
|
out: |
||||||
|
if (sessions) { |
||||||
|
for (i = 0; sessions[i]; i ++) { |
||||||
|
free (sessions[i]); |
||||||
|
} |
||||||
|
|
||||||
|
free (sessions); |
||||||
|
} |
||||||
|
|
||||||
|
return ret; |
||||||
|
} |
||||||
|
|
||||||
|
static void |
||||||
|
activate_login_window_session_on_seat (GdmManager *self, |
||||||
|
const char *seat_id) |
||||||
|
{ |
||||||
|
char *session_id; |
||||||
|
|
||||||
|
if (!get_login_window_session_id (seat_id, &session_id)) { |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
activate_session_id (self, seat_id, session_id); |
||||||
|
} |
||||||
|
|
||||||
|
static void |
||||||
|
maybe_activate_other_session (GdmManager *self, |
||||||
|
GdmDisplay *old_display) |
||||||
|
{ |
||||||
|
-- |
||||||
|
2.19.0 |
||||||
|
|
@ -0,0 +1,654 @@ |
|||||||
|
From b7b492296a69bc5100ff5908048ed5ef121d3587 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Ray Strode <rstrode@redhat.com> |
||||||
|
Date: Mon, 30 Jul 2018 16:21:29 -0400 |
||||||
|
Subject: [PATCH 5/6] daemon: try harder to get to a login screen at logout |
||||||
|
|
||||||
|
commit 22c332ba and some follow up commits try to ensure the |
||||||
|
user never stays on a blank VT by jumping to a login screen in |
||||||
|
the event they'd end up on one. |
||||||
|
|
||||||
|
Unfortunately, that part of the code can't start a login screen |
||||||
|
if there's not one running at all. |
||||||
|
|
||||||
|
This commit moves the code to GdmLocalDisplyFactor where the |
||||||
|
login screens are created, so users won't end up on a blank |
||||||
|
VT even if no login screen is yet running. |
||||||
|
--- |
||||||
|
daemon/gdm-local-display-factory.c | 161 ++++++++++++++++++++++++++++- |
||||||
|
daemon/gdm-manager.c | 54 ---------- |
||||||
|
2 files changed, 156 insertions(+), 59 deletions(-) |
||||||
|
|
||||||
|
diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c |
||||||
|
index b29f5ac52..cf852b55a 100644 |
||||||
|
--- a/daemon/gdm-local-display-factory.c |
||||||
|
+++ b/daemon/gdm-local-display-factory.c |
||||||
|
@@ -1,60 +1,62 @@ |
||||||
|
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- |
||||||
|
* |
||||||
|
* Copyright (C) 2007 William Jon McCann <mccann@jhu.edu> |
||||||
|
* |
||||||
|
* This program is free software; you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU General Public License as published by |
||||||
|
* the Free Software Foundation; either version 2 of the License, or |
||||||
|
* (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU General Public License |
||||||
|
* along with this program; if not, write to the Free Software |
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||||
|
* |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "config.h" |
||||||
|
|
||||||
|
#include <stdlib.h> |
||||||
|
#include <stdio.h> |
||||||
|
|
||||||
|
#include <glib.h> |
||||||
|
#include <glib/gi18n.h> |
||||||
|
#include <glib-object.h> |
||||||
|
#include <gio/gio.h> |
||||||
|
|
||||||
|
+#include <systemd/sd-login.h> |
||||||
|
+ |
||||||
|
#include "gdm-common.h" |
||||||
|
#include "gdm-manager.h" |
||||||
|
#include "gdm-display-factory.h" |
||||||
|
#include "gdm-local-display-factory.h" |
||||||
|
#include "gdm-local-display-factory-glue.h" |
||||||
|
|
||||||
|
#include "gdm-settings-keys.h" |
||||||
|
#include "gdm-settings-direct.h" |
||||||
|
#include "gdm-display-store.h" |
||||||
|
#include "gdm-local-display.h" |
||||||
|
#include "gdm-legacy-display.h" |
||||||
|
|
||||||
|
#define GDM_LOCAL_DISPLAY_FACTORY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_LOCAL_DISPLAY_FACTORY, GdmLocalDisplayFactoryPrivate)) |
||||||
|
|
||||||
|
#define GDM_DBUS_PATH "/org/gnome/DisplayManager" |
||||||
|
#define GDM_LOCAL_DISPLAY_FACTORY_DBUS_PATH GDM_DBUS_PATH "/LocalDisplayFactory" |
||||||
|
#define GDM_MANAGER_DBUS_NAME "org.gnome.DisplayManager.LocalDisplayFactory" |
||||||
|
|
||||||
|
#define MAX_DISPLAY_FAILURES 5 |
||||||
|
|
||||||
|
struct GdmLocalDisplayFactoryPrivate |
||||||
|
{ |
||||||
|
GdmDBusLocalDisplayFactory *skeleton; |
||||||
|
GDBusConnection *connection; |
||||||
|
GHashTable *used_display_numbers; |
||||||
|
|
||||||
|
/* FIXME: this needs to be per seat? */ |
||||||
|
guint num_failures; |
||||||
|
|
||||||
|
guint seat_new_id; |
||||||
|
@@ -226,171 +228,320 @@ gdm_local_display_factory_create_transient_display (GdmLocalDisplayFactory *fact |
||||||
|
store_display (factory, display); |
||||||
|
|
||||||
|
if (! gdm_display_manage (display)) { |
||||||
|
display = NULL; |
||||||
|
goto out; |
||||||
|
} |
||||||
|
|
||||||
|
if (! gdm_display_get_id (display, id, NULL)) { |
||||||
|
display = NULL; |
||||||
|
goto out; |
||||||
|
} |
||||||
|
|
||||||
|
ret = TRUE; |
||||||
|
out: |
||||||
|
/* ref either held by store or not at all */ |
||||||
|
g_object_unref (display); |
||||||
|
|
||||||
|
return ret; |
||||||
|
} |
||||||
|
|
||||||
|
static void |
||||||
|
on_display_status_changed (GdmDisplay *display, |
||||||
|
GParamSpec *arg1, |
||||||
|
GdmLocalDisplayFactory *factory) |
||||||
|
{ |
||||||
|
int status; |
||||||
|
GdmDisplayStore *store; |
||||||
|
int num; |
||||||
|
char *seat_id = NULL; |
||||||
|
char *session_type = NULL; |
||||||
|
+ char *session_class = NULL; |
||||||
|
gboolean is_initial = TRUE; |
||||||
|
gboolean is_local = TRUE; |
||||||
|
|
||||||
|
num = -1; |
||||||
|
gdm_display_get_x11_display_number (display, &num, NULL); |
||||||
|
|
||||||
|
store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory)); |
||||||
|
|
||||||
|
g_object_get (display, |
||||||
|
"seat-id", &seat_id, |
||||||
|
"is-initial", &is_initial, |
||||||
|
"is-local", &is_local, |
||||||
|
"session-type", &session_type, |
||||||
|
+ "session-class", &session_class, |
||||||
|
NULL); |
||||||
|
|
||||||
|
status = gdm_display_get_status (display); |
||||||
|
|
||||||
|
g_debug ("GdmLocalDisplayFactory: display status changed: %d", status); |
||||||
|
switch (status) { |
||||||
|
case GDM_DISPLAY_FINISHED: |
||||||
|
/* remove the display number from factory->priv->used_display_numbers |
||||||
|
so that it may be reused */ |
||||||
|
if (num != -1) { |
||||||
|
g_hash_table_remove (factory->priv->used_display_numbers, GUINT_TO_POINTER (num)); |
||||||
|
} |
||||||
|
gdm_display_store_remove (store, display); |
||||||
|
|
||||||
|
/* if this is a local display, do a full resync. Only |
||||||
|
* seats without displays will get created anyway. This |
||||||
|
* ensures we get a new login screen when the user logs out, |
||||||
|
* if there isn't one. |
||||||
|
*/ |
||||||
|
- if (is_local) { |
||||||
|
+ if (is_local && g_strcmp0 (session_class, "greeter") != 0) { |
||||||
|
/* reset num failures */ |
||||||
|
factory->priv->num_failures = 0; |
||||||
|
|
||||||
|
gdm_local_display_factory_sync_seats (factory); |
||||||
|
} |
||||||
|
break; |
||||||
|
case GDM_DISPLAY_FAILED: |
||||||
|
/* leave the display number in factory->priv->used_display_numbers |
||||||
|
so that it doesn't get reused */ |
||||||
|
gdm_display_store_remove (store, display); |
||||||
|
|
||||||
|
/* Create a new equivalent display if it was static */ |
||||||
|
if (is_local) { |
||||||
|
|
||||||
|
factory->priv->num_failures++; |
||||||
|
|
||||||
|
if (factory->priv->num_failures > MAX_DISPLAY_FAILURES) { |
||||||
|
/* oh shit */ |
||||||
|
g_warning ("GdmLocalDisplayFactory: maximum number of X display failures reached: check X server log for errors"); |
||||||
|
} else { |
||||||
|
#ifdef ENABLE_WAYLAND_SUPPORT |
||||||
|
if (g_strcmp0 (session_type, "wayland") == 0) { |
||||||
|
g_free (session_type); |
||||||
|
session_type = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
#endif |
||||||
|
create_display (factory, seat_id, session_type, is_initial); |
||||||
|
} |
||||||
|
} |
||||||
|
break; |
||||||
|
case GDM_DISPLAY_UNMANAGED: |
||||||
|
break; |
||||||
|
case GDM_DISPLAY_PREPARED: |
||||||
|
break; |
||||||
|
case GDM_DISPLAY_MANAGED: |
||||||
|
break; |
||||||
|
default: |
||||||
|
g_assert_not_reached (); |
||||||
|
break; |
||||||
|
} |
||||||
|
|
||||||
|
g_free (seat_id); |
||||||
|
g_free (session_type); |
||||||
|
+ g_free (session_class); |
||||||
|
} |
||||||
|
|
||||||
|
static gboolean |
||||||
|
lookup_by_seat_id (const char *id, |
||||||
|
GdmDisplay *display, |
||||||
|
gpointer user_data) |
||||||
|
{ |
||||||
|
const char *looking_for = user_data; |
||||||
|
char *current; |
||||||
|
gboolean res; |
||||||
|
|
||||||
|
g_object_get (G_OBJECT (display), "seat-id", ¤t, NULL); |
||||||
|
|
||||||
|
res = g_strcmp0 (current, looking_for) == 0; |
||||||
|
|
||||||
|
g_free(current); |
||||||
|
|
||||||
|
return res; |
||||||
|
} |
||||||
|
|
||||||
|
+static gboolean |
||||||
|
+activate_session_id (GdmLocalDisplayFactory *self, |
||||||
|
+ const char *seat_id, |
||||||
|
+ const char *session_id) |
||||||
|
+{ |
||||||
|
+ GError *error = NULL; |
||||||
|
+ GVariant *reply; |
||||||
|
+ |
||||||
|
+ reply = g_dbus_connection_call_sync (self->priv->connection, |
||||||
|
+ "org.freedesktop.login1", |
||||||
|
+ "/org/freedesktop/login1", |
||||||
|
+ "org.freedesktop.login1.Manager", |
||||||
|
+ "ActivateSessionOnSeat", |
||||||
|
+ g_variant_new ("(ss)", session_id, seat_id), |
||||||
|
+ NULL, /* expected reply */ |
||||||
|
+ G_DBUS_CALL_FLAGS_NONE, |
||||||
|
+ -1, |
||||||
|
+ NULL, |
||||||
|
+ &error); |
||||||
|
+ if (reply == NULL) { |
||||||
|
+ g_debug ("GdmManager: logind 'ActivateSessionOnSeat' %s raised:\n %s\n\n", |
||||||
|
+ g_dbus_error_get_remote_error (error), error->message); |
||||||
|
+ g_error_free (error); |
||||||
|
+ return FALSE; |
||||||
|
+ } |
||||||
|
+ |
||||||
|
+ g_variant_unref (reply); |
||||||
|
+ |
||||||
|
+ return TRUE; |
||||||
|
+} |
||||||
|
+ |
||||||
|
+static gboolean |
||||||
|
+get_login_window_session_id (const char *seat_id, |
||||||
|
+ char **session_id) |
||||||
|
+{ |
||||||
|
+ gboolean ret; |
||||||
|
+ int res, i; |
||||||
|
+ char **sessions; |
||||||
|
+ char *service_id; |
||||||
|
+ char *service_class; |
||||||
|
+ char *state; |
||||||
|
+ |
||||||
|
+ res = sd_seat_get_sessions (seat_id, &sessions, NULL, NULL); |
||||||
|
+ if (res < 0) { |
||||||
|
+ g_debug ("Failed to determine sessions: %s", strerror (-res)); |
||||||
|
+ return FALSE; |
||||||
|
+ } |
||||||
|
+ |
||||||
|
+ if (sessions == NULL || sessions[0] == NULL) { |
||||||
|
+ *session_id = NULL; |
||||||
|
+ ret = TRUE; |
||||||
|
+ goto out; |
||||||
|
+ } |
||||||
|
+ |
||||||
|
+ for (i = 0; sessions[i]; i ++) { |
||||||
|
+ |
||||||
|
+ res = sd_session_get_class (sessions[i], &service_class); |
||||||
|
+ if (res < 0) { |
||||||
|
+ if (res == -ENOENT || res == -ENXIO) { |
||||||
|
+ continue; |
||||||
|
+ } |
||||||
|
+ |
||||||
|
+ g_debug ("failed to determine class of session %s: %s", sessions[i], strerror (-res)); |
||||||
|
+ ret = FALSE; |
||||||
|
+ goto out; |
||||||
|
+ } |
||||||
|
+ |
||||||
|
+ if (strcmp (service_class, "greeter") != 0) { |
||||||
|
+ free (service_class); |
||||||
|
+ continue; |
||||||
|
+ } |
||||||
|
+ |
||||||
|
+ free (service_class); |
||||||
|
+ |
||||||
|
+ ret = sd_session_get_state (sessions[i], &state); |
||||||
|
+ if (ret < 0) { |
||||||
|
+ if (res == -ENOENT || res == -ENXIO) |
||||||
|
+ continue; |
||||||
|
+ |
||||||
|
+ g_debug ("failed to determine state of session %s: %s", sessions[i], strerror (-res)); |
||||||
|
+ ret = FALSE; |
||||||
|
+ goto out; |
||||||
|
+ } |
||||||
|
+ |
||||||
|
+ if (g_strcmp0 (state, "closing") == 0) { |
||||||
|
+ free (state); |
||||||
|
+ continue; |
||||||
|
+ } |
||||||
|
+ free (state); |
||||||
|
+ |
||||||
|
+ res = sd_session_get_service (sessions[i], &service_id); |
||||||
|
+ if (res < 0) { |
||||||
|
+ if (res == -ENOENT || res == -ENXIO) |
||||||
|
+ continue; |
||||||
|
+ g_debug ("failed to determine service of session %s: %s", sessions[i], strerror (-res)); |
||||||
|
+ ret = FALSE; |
||||||
|
+ goto out; |
||||||
|
+ } |
||||||
|
+ |
||||||
|
+ if (strcmp (service_id, "gdm-launch-environment") == 0) { |
||||||
|
+ *session_id = g_strdup (sessions[i]); |
||||||
|
+ ret = TRUE; |
||||||
|
+ |
||||||
|
+ free (service_id); |
||||||
|
+ goto out; |
||||||
|
+ } |
||||||
|
+ |
||||||
|
+ free (service_id); |
||||||
|
+ } |
||||||
|
+ |
||||||
|
+ *session_id = NULL; |
||||||
|
+ ret = FALSE; |
||||||
|
+ |
||||||
|
+out: |
||||||
|
+ if (sessions) { |
||||||
|
+ for (i = 0; sessions[i]; i ++) { |
||||||
|
+ free (sessions[i]); |
||||||
|
+ } |
||||||
|
+ |
||||||
|
+ free (sessions); |
||||||
|
+ } |
||||||
|
+ |
||||||
|
+ return ret; |
||||||
|
+} |
||||||
|
+ |
||||||
|
static GdmDisplay * |
||||||
|
create_display (GdmLocalDisplayFactory *factory, |
||||||
|
const char *seat_id, |
||||||
|
const char *session_type, |
||||||
|
gboolean initial) |
||||||
|
{ |
||||||
|
GdmDisplayStore *store; |
||||||
|
GdmDisplay *display = NULL; |
||||||
|
+ char *active_session_id = NULL; |
||||||
|
+ int ret; |
||||||
|
|
||||||
|
- /* Ensure we don't create the same display more than once */ |
||||||
|
store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory)); |
||||||
|
- display = gdm_display_store_find (store, lookup_by_seat_id, (gpointer) seat_id); |
||||||
|
- if (display != NULL) { |
||||||
|
- return NULL; |
||||||
|
+ |
||||||
|
+ ret = sd_seat_get_active (seat_id, &active_session_id, NULL); |
||||||
|
+ |
||||||
|
+ if (ret == 0) { |
||||||
|
+ char *login_session_id = NULL; |
||||||
|
+ |
||||||
|
+ /* If we already have a login window, switch to it */ |
||||||
|
+ if (get_login_window_session_id (seat_id, &login_session_id)) { |
||||||
|
+ if (g_strcmp0 (active_session_id, login_session_id) != 0) { |
||||||
|
+ activate_session_id (factory, seat_id, login_session_id); |
||||||
|
+ } |
||||||
|
+ g_clear_pointer (&login_session_id, g_free); |
||||||
|
+ g_clear_pointer (&active_session_id, g_free); |
||||||
|
+ return NULL; |
||||||
|
+ } |
||||||
|
+ g_clear_pointer (&active_session_id, g_free); |
||||||
|
+ } else { |
||||||
|
+ /* Ensure we don't create the same display more than once */ |
||||||
|
+ display = gdm_display_store_find (store, lookup_by_seat_id, (gpointer) seat_id); |
||||||
|
+ |
||||||
|
+ if (display != NULL) { |
||||||
|
+ return NULL; |
||||||
|
+ } |
||||||
|
} |
||||||
|
|
||||||
|
g_debug ("GdmLocalDisplayFactory: Adding display on seat %s", seat_id); |
||||||
|
|
||||||
|
#ifdef ENABLE_USER_DISPLAY_SERVER |
||||||
|
if (g_strcmp0 (seat_id, "seat0") == 0) { |
||||||
|
display = gdm_local_display_new (); |
||||||
|
if (session_type != NULL) { |
||||||
|
g_object_set (G_OBJECT (display), "session-type", session_type, NULL); |
||||||
|
} |
||||||
|
} |
||||||
|
#endif |
||||||
|
|
||||||
|
if (display == NULL) { |
||||||
|
guint32 num; |
||||||
|
|
||||||
|
num = take_next_display_number (factory); |
||||||
|
|
||||||
|
display = gdm_legacy_display_new (num); |
||||||
|
} |
||||||
|
|
||||||
|
g_object_set (display, "seat-id", seat_id, NULL); |
||||||
|
g_object_set (display, "is-initial", initial, NULL); |
||||||
|
|
||||||
|
store_display (factory, display); |
||||||
|
|
||||||
|
/* let store own the ref */ |
||||||
|
g_object_unref (display); |
||||||
|
|
||||||
|
if (! gdm_display_manage (display)) { |
||||||
|
diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c |
||||||
|
index 34ee74033..031c61ce6 100644 |
||||||
|
--- a/daemon/gdm-manager.c |
||||||
|
+++ b/daemon/gdm-manager.c |
||||||
|
@@ -1318,171 +1318,118 @@ maybe_start_pending_initial_login (GdmManager *manager, |
||||||
|
g_free (user_session_seat_id); |
||||||
|
} |
||||||
|
|
||||||
|
static gboolean |
||||||
|
get_login_window_session_id (const char *seat_id, |
||||||
|
char **session_id) |
||||||
|
{ |
||||||
|
gboolean ret; |
||||||
|
int res, i; |
||||||
|
char **sessions; |
||||||
|
char *service_id; |
||||||
|
char *service_class; |
||||||
|
char *state; |
||||||
|
|
||||||
|
res = sd_seat_get_sessions (seat_id, &sessions, NULL, NULL); |
||||||
|
if (res < 0) { |
||||||
|
g_debug ("Failed to determine sessions: %s", strerror (-res)); |
||||||
|
return FALSE; |
||||||
|
} |
||||||
|
|
||||||
|
if (sessions == NULL || sessions[0] == NULL) { |
||||||
|
*session_id = NULL; |
||||||
|
ret = FALSE; |
||||||
|
goto out; |
||||||
|
} |
||||||
|
|
||||||
|
for (i = 0; sessions[i]; i ++) { |
||||||
|
|
||||||
|
res = sd_session_get_class (sessions[i], &service_class); |
||||||
|
if (res < 0) { |
||||||
|
- if (res == -ENOENT || res == -ENXIO) { |
||||||
|
- continue; |
||||||
|
- } |
||||||
|
- |
||||||
|
g_debug ("failed to determine class of session %s: %s", sessions[i], strerror (-res)); |
||||||
|
ret = FALSE; |
||||||
|
goto out; |
||||||
|
} |
||||||
|
|
||||||
|
if (strcmp (service_class, "greeter") != 0) { |
||||||
|
free (service_class); |
||||||
|
continue; |
||||||
|
} |
||||||
|
|
||||||
|
free (service_class); |
||||||
|
|
||||||
|
ret = sd_session_get_state (sessions[i], &state); |
||||||
|
if (ret < 0) { |
||||||
|
- if (res == -ENOENT || res == -ENXIO) |
||||||
|
- continue; |
||||||
|
- |
||||||
|
g_debug ("failed to determine state of session %s: %s", sessions[i], strerror (-res)); |
||||||
|
ret = FALSE; |
||||||
|
goto out; |
||||||
|
} |
||||||
|
|
||||||
|
if (g_strcmp0 (state, "closing") == 0) { |
||||||
|
free (state); |
||||||
|
continue; |
||||||
|
} |
||||||
|
free (state); |
||||||
|
|
||||||
|
res = sd_session_get_service (sessions[i], &service_id); |
||||||
|
if (res < 0) { |
||||||
|
- if (res == -ENOENT || res == -ENXIO) |
||||||
|
- continue; |
||||||
|
g_debug ("failed to determine service of session %s: %s", sessions[i], strerror (-res)); |
||||||
|
ret = FALSE; |
||||||
|
goto out; |
||||||
|
} |
||||||
|
|
||||||
|
if (strcmp (service_id, "gdm-launch-environment") == 0) { |
||||||
|
*session_id = g_strdup (sessions[i]); |
||||||
|
ret = TRUE; |
||||||
|
|
||||||
|
free (service_id); |
||||||
|
goto out; |
||||||
|
} |
||||||
|
|
||||||
|
free (service_id); |
||||||
|
} |
||||||
|
|
||||||
|
*session_id = NULL; |
||||||
|
ret = FALSE; |
||||||
|
|
||||||
|
out: |
||||||
|
if (sessions) { |
||||||
|
for (i = 0; sessions[i]; i ++) { |
||||||
|
free (sessions[i]); |
||||||
|
} |
||||||
|
|
||||||
|
free (sessions); |
||||||
|
} |
||||||
|
|
||||||
|
return ret; |
||||||
|
} |
||||||
|
|
||||||
|
-static void |
||||||
|
-activate_login_window_session_on_seat (GdmManager *self, |
||||||
|
- const char *seat_id) |
||||||
|
-{ |
||||||
|
- char *session_id; |
||||||
|
- |
||||||
|
- if (!get_login_window_session_id (seat_id, &session_id)) { |
||||||
|
- return; |
||||||
|
- } |
||||||
|
- |
||||||
|
- activate_session_id (self, seat_id, session_id); |
||||||
|
-} |
||||||
|
- |
||||||
|
-static void |
||||||
|
-maybe_activate_other_session (GdmManager *self, |
||||||
|
- GdmDisplay *old_display) |
||||||
|
-{ |
||||||
|
- char *seat_id = NULL; |
||||||
|
- char *session_id = NULL; |
||||||
|
- int ret; |
||||||
|
- |
||||||
|
- g_object_get (G_OBJECT (old_display), |
||||||
|
- "seat-id", &seat_id, |
||||||
|
- NULL); |
||||||
|
- |
||||||
|
- ret = sd_seat_get_active (seat_id, &session_id, NULL); |
||||||
|
- |
||||||
|
- if (ret == 0) { |
||||||
|
- GdmDisplay *display; |
||||||
|
- |
||||||
|
- display = gdm_display_store_find (self->priv->display_store, |
||||||
|
- lookup_by_session_id, |
||||||
|
- (gpointer) session_id); |
||||||
|
- |
||||||
|
- if (display == NULL || gdm_display_get_status (display) == GDM_DISPLAY_FINISHED) { |
||||||
|
- activate_login_window_session_on_seat (self, seat_id); |
||||||
|
- } |
||||||
|
- |
||||||
|
- g_free (session_id); |
||||||
|
- } |
||||||
|
- |
||||||
|
- g_free (seat_id); |
||||||
|
-} |
||||||
|
- |
||||||
|
static const char * |
||||||
|
get_username_for_greeter_display (GdmManager *manager, |
||||||
|
GdmDisplay *display) |
||||||
|
{ |
||||||
|
gboolean doing_initial_setup = FALSE; |
||||||
|
|
||||||
|
g_object_get (G_OBJECT (display), |
||||||
|
"doing-initial-setup", &doing_initial_setup, |
||||||
|
NULL); |
||||||
|
|
||||||
|
if (doing_initial_setup) { |
||||||
|
return INITIAL_SETUP_USERNAME; |
||||||
|
} else { |
||||||
|
return GDM_USERNAME; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
static void |
||||||
|
set_up_automatic_login_session (GdmManager *manager, |
||||||
|
GdmDisplay *display) |
||||||
|
{ |
||||||
|
GdmSession *session; |
||||||
|
char *display_session_type = NULL; |
||||||
|
gboolean is_initial; |
||||||
|
|
||||||
|
/* 0 is root user; since the daemon talks to the session object |
||||||
|
* directly, itself, for automatic login |
||||||
|
*/ |
||||||
|
session = create_user_session_for_display (manager, display, 0); |
||||||
|
|
||||||
|
@@ -1674,61 +1621,60 @@ on_display_status_changed (GdmDisplay *display, |
||||||
|
if ((display_number == -1 && status == GDM_DISPLAY_PREPARED) || |
||||||
|
(display_number != -1 && status == GDM_DISPLAY_MANAGED)) { |
||||||
|
char *session_class; |
||||||
|
|
||||||
|
g_object_get (display, |
||||||
|
"session-class", &session_class, |
||||||
|
NULL); |
||||||
|
if (g_strcmp0 (session_class, "greeter") == 0) |
||||||
|
set_up_session (manager, display); |
||||||
|
g_free (session_class); |
||||||
|
} |
||||||
|
|
||||||
|
if (status == GDM_DISPLAY_MANAGED) { |
||||||
|
greeter_display_started (manager, display); |
||||||
|
} |
||||||
|
break; |
||||||
|
case GDM_DISPLAY_FAILED: |
||||||
|
case GDM_DISPLAY_UNMANAGED: |
||||||
|
case GDM_DISPLAY_FINISHED: |
||||||
|
#ifdef WITH_PLYMOUTH |
||||||
|
if (quit_plymouth) { |
||||||
|
plymouth_quit_without_transition (); |
||||||
|
manager->priv->plymouth_is_running = FALSE; |
||||||
|
} |
||||||
|
#endif |
||||||
|
|
||||||
|
if (status == GDM_DISPLAY_FINISHED || g_strcmp0 (session_type, "x11") == 0) { |
||||||
|
manager->priv->ran_once = TRUE; |
||||||
|
} |
||||||
|
maybe_start_pending_initial_login (manager, display); |
||||||
|
- maybe_activate_other_session (manager, display); |
||||||
|
break; |
||||||
|
default: |
||||||
|
break; |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
static void |
||||||
|
on_display_removed (GdmDisplayStore *display_store, |
||||||
|
const char *id, |
||||||
|
GdmManager *manager) |
||||||
|
{ |
||||||
|
GdmDisplay *display; |
||||||
|
|
||||||
|
display = gdm_display_store_lookup (display_store, id); |
||||||
|
if (display != NULL) { |
||||||
|
g_dbus_object_manager_server_unexport (manager->priv->object_manager, id); |
||||||
|
|
||||||
|
g_signal_handlers_disconnect_by_func (display, G_CALLBACK (on_display_status_changed), manager); |
||||||
|
|
||||||
|
g_signal_emit (manager, signals[DISPLAY_REMOVED], 0, id); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
static void |
||||||
|
destroy_start_user_session_operation (StartUserSessionOperation *operation) |
||||||
|
{ |
||||||
|
g_object_set_data (G_OBJECT (operation->session), |
||||||
|
"start-user-session-operation", |
||||||
|
NULL); |
||||||
|
-- |
||||||
|
2.19.0 |
||||||
|
|
@ -0,0 +1,97 @@ |
|||||||
|
From 91eee14bcd2447d78ad00e3de9d4380e423cb897 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Ray Strode <rstrode@redhat.com> |
||||||
|
Date: Mon, 24 Sep 2018 10:53:53 -0400 |
||||||
|
Subject: [PATCH 6/6] daemon: ensure is-initial bit is transferred to new login |
||||||
|
screen at logout |
||||||
|
|
||||||
|
At the moment, when a user logs out we call sync_seats to restart the |
||||||
|
login screen. sync_seats doesn't know whether or not vt1 is occupied. |
||||||
|
|
||||||
|
This commit changes the code to call the more targeted `create_display` |
||||||
|
function, which we can inform of vt1's availability by the is_initial |
||||||
|
flag. |
||||||
|
--- |
||||||
|
daemon/gdm-local-display-factory.c | 8 +++----- |
||||||
|
1 file changed, 3 insertions(+), 5 deletions(-) |
||||||
|
|
||||||
|
diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c |
||||||
|
index cf852b55a..9a07f03ed 100644 |
||||||
|
--- a/daemon/gdm-local-display-factory.c |
||||||
|
+++ b/daemon/gdm-local-display-factory.c |
||||||
|
@@ -257,70 +257,68 @@ on_display_status_changed (GdmDisplay *display, |
||||||
|
char *session_type = NULL; |
||||||
|
char *session_class = NULL; |
||||||
|
gboolean is_initial = TRUE; |
||||||
|
gboolean is_local = TRUE; |
||||||
|
|
||||||
|
num = -1; |
||||||
|
gdm_display_get_x11_display_number (display, &num, NULL); |
||||||
|
|
||||||
|
store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory)); |
||||||
|
|
||||||
|
g_object_get (display, |
||||||
|
"seat-id", &seat_id, |
||||||
|
"is-initial", &is_initial, |
||||||
|
"is-local", &is_local, |
||||||
|
"session-type", &session_type, |
||||||
|
"session-class", &session_class, |
||||||
|
NULL); |
||||||
|
|
||||||
|
status = gdm_display_get_status (display); |
||||||
|
|
||||||
|
g_debug ("GdmLocalDisplayFactory: display status changed: %d", status); |
||||||
|
switch (status) { |
||||||
|
case GDM_DISPLAY_FINISHED: |
||||||
|
/* remove the display number from factory->priv->used_display_numbers |
||||||
|
so that it may be reused */ |
||||||
|
if (num != -1) { |
||||||
|
g_hash_table_remove (factory->priv->used_display_numbers, GUINT_TO_POINTER (num)); |
||||||
|
} |
||||||
|
gdm_display_store_remove (store, display); |
||||||
|
|
||||||
|
- /* if this is a local display, do a full resync. Only |
||||||
|
- * seats without displays will get created anyway. This |
||||||
|
- * ensures we get a new login screen when the user logs out, |
||||||
|
- * if there isn't one. |
||||||
|
+ /* if this is a local display, recreate the display so |
||||||
|
+ * a new login screen comes up if one is missing. |
||||||
|
*/ |
||||||
|
if (is_local && g_strcmp0 (session_class, "greeter") != 0) { |
||||||
|
/* reset num failures */ |
||||||
|
factory->priv->num_failures = 0; |
||||||
|
|
||||||
|
- gdm_local_display_factory_sync_seats (factory); |
||||||
|
+ create_display (factory, seat_id, session_type, is_initial); |
||||||
|
} |
||||||
|
break; |
||||||
|
case GDM_DISPLAY_FAILED: |
||||||
|
/* leave the display number in factory->priv->used_display_numbers |
||||||
|
so that it doesn't get reused */ |
||||||
|
gdm_display_store_remove (store, display); |
||||||
|
|
||||||
|
/* Create a new equivalent display if it was static */ |
||||||
|
if (is_local) { |
||||||
|
|
||||||
|
factory->priv->num_failures++; |
||||||
|
|
||||||
|
if (factory->priv->num_failures > MAX_DISPLAY_FAILURES) { |
||||||
|
/* oh shit */ |
||||||
|
g_warning ("GdmLocalDisplayFactory: maximum number of X display failures reached: check X server log for errors"); |
||||||
|
} else { |
||||||
|
#ifdef ENABLE_WAYLAND_SUPPORT |
||||||
|
if (g_strcmp0 (session_type, "wayland") == 0) { |
||||||
|
g_free (session_type); |
||||||
|
session_type = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
#endif |
||||||
|
create_display (factory, seat_id, session_type, is_initial); |
||||||
|
} |
||||||
|
} |
||||||
|
break; |
||||||
|
case GDM_DISPLAY_UNMANAGED: |
||||||
|
break; |
||||||
|
case GDM_DISPLAY_PREPARED: |
||||||
|
-- |
||||||
|
2.19.0 |
||||||
|
|
Loading…
Reference in new issue