From 67d29b19ff4e53d58879b14c2e79a3bda419576f Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Fri, 22 Jun 2018 15:26:03 -0400
Subject: [PATCH 11/51] 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 | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c
index a6f13dec7..ede22e771 100644
--- a/daemon/gdm-manager.c
+++ b/daemon/gdm-manager.c
@@ -1349,87 +1349,97 @@ 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) {
+ free (service_class);
+ 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)
+ 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)
+ 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;
}
--
2.27.0