Blob Blame History Raw
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